1
0
Fork 0
forked from fun/fun

Added tons of AI generated docs and a lot of cleanups. No code changes. (0.41.5)

This commit is contained in:
Johannes Findeisen 2026-05-01 02:20:25 +02:00
commit 4e69a3ce63
151 changed files with 3897 additions and 427 deletions

View file

@ -1,25 +1,58 @@
/*
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2026 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-27
*/
// Use an FFI-safe opaque handle for the VM pointer
/**
* Rust FFI entry points and helpers used by the Fun VM (C).
*
* This crate builds a static library that exposes a handful of C-ABI
* functions callable by the C VM. The functions operate on an opaque VM
* pointer and follow the same conventions as native C opcode handlers:
* they return 0 on success and nonzero on error, and they communicate
* values via VM stack helpers provided on the C side.
*
* Safety
* - All extern "C" functions are inherently unsafe due to raw pointers.
* - Callers must pass valid VM pointers provided by the C runtime.
* - Any strings returned across the FFI boundary are NULterminated and
* must be freed using the dedicated free function documented below.
*/
/// Use an FFIsafe opaque handle for the VM pointer owned by the C VM.
///
/// The Rust code treats this as an opaque blob and never dereferences it
/// directly, relying instead on C helper functions exposed via FFI.
pub type Vm = core::ffi::c_void;
extern "C" {
/// Pop a 64bit integer from the VM stack.
///
/// Safety: `vm` must be a valid pointer to a VM instance.
fn vm_pop_i64(vm: *mut Vm) -> i64;
/// Push a 64bit integer onto the VM stack.
///
/// Safety: `vm` must be a valid pointer to a VM instance.
fn vm_push_i64(vm: *mut Vm, v: i64);
}
// Submodule with additional Rust VM math ops (exported via C ABI)
/// Submodule with additional Rust VM math ops (exported via C ABI).
pub mod vm;
/// Add the top two integers on the VM stack.
///
/// Stack effect
/// - Before: [..., a, b]
/// - After: [..., a+b]
///
/// Return value
/// - 0 on success; nonzero on error (never used here).
///
/// Safety: `vm` must be a valid VM pointer.
#[no_mangle]
pub extern "C" fn fun_op_radd(vm: *mut Vm) -> i32 {
unsafe {
@ -30,12 +63,26 @@ pub extern "C" fn fun_op_radd(vm: *mut Vm) -> i32 {
0
}
/// Return a static NULterminated greeting string owned by Rust.
///
/// The returned pointer remains valid for the duration of the process and
/// must NOT be freed by the caller.
///
/// Return const char* to a constant "Hello from Rust ops!" string.
#[no_mangle]
pub extern "C" fn fun_rust_get_string() -> *const core::ffi::c_char {
b"Hello from Rust ops!\0".as_ptr() as *const _
}
// Print a C string via libc printf to stdout
/// Print a C string to stdout using libc printf("%s\n").
///
/// - If `msg` is NULL, behavior is undefined (printf will likely crash).
/// - This is intended as a simple demo and not for performancecritical use.
///
/// Param msg NULterminated UTF8/bytes C string.
/// Return 0 on success.
///
/// Safety: `msg` must be a valid C string pointer when nonNULL.
#[no_mangle]
pub extern "C" fn fun_rust_print_string(msg: *const core::ffi::c_char) -> i32 {
unsafe {
@ -48,8 +95,17 @@ pub extern "C" fn fun_rust_print_string(msg: *const core::ffi::c_char) -> i32 {
0
}
// Return a newly allocated duplicate of the given C string.
// Caller (C side) must free using fun_rust_string_free.
/// Duplicate a C string and return an owned copy allocated by Rust.
///
/// - On NULL input, returns an allocated empty string ("\0").
/// - On invalid UTF8, the raw byte sequence is duplicated asis.
/// - Memory ownership is transferred to the caller, who must free it with
/// fun_rust_string_free().
///
/// Param input NULterminated C string (may be NULL).
/// Return Newly allocated NULterminated C string owned by the caller.
///
/// Safety: `input` must be a valid pointer if nonNULL.
#[no_mangle]
pub extern "C" fn fun_rust_echo_string(input: *const core::ffi::c_char) -> *mut core::ffi::c_char {
use core::ffi::CStr;
@ -76,7 +132,13 @@ pub extern "C" fn fun_rust_echo_string(input: *const core::ffi::c_char) -> *mut
}
}
// Free a C string previously returned by fun_rust_echo_string
/// Free a C string allocated by fun_rust_echo_string().
///
/// The pointer may be NULL, in which case the function is a noop.
///
/// Param ptr Pointer returned by fun_rust_echo_string().
///
/// Safety: `ptr` must have been allocated by fun_rust_echo_string().
#[no_mangle]
pub extern "C" fn fun_rust_string_free(ptr: *mut core::ffi::c_char) {
if ptr.is_null() { return; }
@ -90,4 +152,4 @@ pub extern "C" fn fun_rust_string_free(ptr: *mut core::ffi::c_char) {
}
}
// No custom panic handler; use std default
// No custom panic handler; use std default.

View file

@ -1,32 +1,45 @@
/*
/**
* This file is part of the Fun programming language.
* https://fun-lang.xyz/
*
* Copyright 2026 Johannes Findeisen <you@hanez.org>
* Licensed under the terms of the Apache-2.0 license.
* https://opensource.org/license/apache-2-0
*
* Added: 2026-01-27
*/
//! Rust VM helpers and opcode handlers exposed via C ABI.
//!
//! Functions in this module are compiled into the Rust static library and can
//! be called from the C VM. They operate on the VM stack using the minimal C
//! ABI helpers declared on the C side (`vm_pop_i64`, `vm_push_i64`).
/**
* Rust VM helpers and opcode handlers exposed via C ABI.
*
* Functions in this module are compiled into the Rust static library and can
* be called from the C VM. They operate on the VM stack using the minimal C
* ABI helpers declared on the C side (e.g. `vm_pop_i64`, `vm_push_i64`).
*
* Safety
* - All extern "C" functions are unsafe; `vm` must be a valid pointer.
* - Raw field access helpers (offset reads/writes) assume the C `struct Vm`
* layout matches the offsets reported by the C side.
*/
use super::Vm;
//use core::mem::size_of;
use core::ptr;
extern "C" {
/// Pop a 64bit integer from the VM stack.
fn vm_pop_i64(vm: *mut Vm) -> i64;
/// Push a 64bit integer onto the VM stack.
fn vm_push_i64(vm: *mut Vm, v: i64);
/// Get a mutable pointer to the underlying C Vm as an opaque byte ptr.
fn vm_as_mut_ptr(vm: *mut Vm) -> *mut core::ffi::c_void;
/// Size of the C Vm struct (bytes).
fn vm_sizeof() -> usize;
/// Size of the C Value struct (bytes).
fn vm_value_sizeof() -> usize;
/// Byte offset of the `exit_code` field inside C Vm.
fn vm_offset_of_exit_code() -> usize;
/// Byte offset of the `sp` field inside C Vm.
fn vm_offset_of_sp() -> usize;
/// Byte offset of the `stack` field inside C Vm.
fn vm_offset_of_stack() -> usize;
}