mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 22:28:45 +01:00
Tweak some docs a little.
This commit is contained in:
@ -1,6 +1,102 @@
|
||||
^title Calling C from Wren
|
||||
|
||||
**TODO: Write these docs.**
|
||||
- foreign class
|
||||
- foreign method
|
||||
|
||||
- WrenBindForeignMethodFn
|
||||
- finalizers (WrenFinalizerFn)
|
||||
- WrenBindForeignClassFn
|
||||
- WrenForeignClassMethods
|
||||
- bindForeignMethodFn
|
||||
- bindForeignClassFn
|
||||
|
||||
- wren vm reaches out to c for two things, raw data and behavior written in c
|
||||
- wren is oop so data is stored in instances of classes
|
||||
- foreign classes
|
||||
- likewise, behavior in methods, so foreign methods
|
||||
- foreign methods
|
||||
- want to call code in wren, invoke method
|
||||
- want to call c code, still invoke method
|
||||
- declaring:
|
||||
- just that method is implemented in c
|
||||
- bit like "native" in java
|
||||
- need to tell wren that method is declared on class but implementation is
|
||||
in c
|
||||
- "foreign"
|
||||
- can be instance or static
|
||||
- binding:
|
||||
- wren needs to find corresponding c fn to call for it
|
||||
- uses pull model
|
||||
- when class decl is executed, wren asks embedder for pointer to c fn
|
||||
- when configure vm, give it bindForeignMethodFn
|
||||
- this is called every time foreign method decl is executed
|
||||
- tells you module, class, and sig of method
|
||||
- your job is to return proper c fn for that method
|
||||
- wren wires two together then calls c fn whenever method is called
|
||||
- looking up class and sig by name kind of slow and tedious
|
||||
- but only done once when class decl itself executes
|
||||
- after that, remembers binding
|
||||
- calling:
|
||||
- when foreign method is called, wren sets up slots
|
||||
- then calls c fn
|
||||
- receiver in slot zero, other args in later slots
|
||||
- do whatever work you want in c
|
||||
- can modify slot array
|
||||
- put return value in slot zero
|
||||
|
||||
**TODO: next page**
|
||||
|
||||
- foreign classes
|
||||
- embedded language often need to work with native c data
|
||||
- maybe want to refer to pointer to memory in c heap
|
||||
- maybe want more dense efficient encoding c provides
|
||||
- may want to refer to resource otherwise managed outside of wren, like file
|
||||
handle
|
||||
- wrap in foreign class
|
||||
- hybrid of wren and c
|
||||
- foreign class has methods defined in wren (though can be foreign)
|
||||
- each instance is instance of wren class, knows type, etc.
|
||||
- but also stores bytes of data opaque to wren
|
||||
- defining:
|
||||
- "foreign class"
|
||||
- declaring class foreign says "when construct call into c to fill in
|
||||
opaque bytes"
|
||||
- need c fn pointer to do that work
|
||||
- like method, bound when class is declared
|
||||
- bindForeignClassFn
|
||||
- takes two pointers, ctor and finalizer
|
||||
- initializing:
|
||||
- whenever construct instance of foreign class, calls fn
|
||||
- call wrenSetSlotNewForeign() to create instance and tell it how many
|
||||
bytes to allocate
|
||||
- returns void* to opaque data
|
||||
- initialize as see fit
|
||||
- accessing:
|
||||
- data opaque, can't be too opaque, need to use it!
|
||||
- cannot access from within wren, only c
|
||||
- if have instance of foreign class in slot, wrenGetSlotForeign() returns
|
||||
void* to raw data
|
||||
- typically, used if foreign method defined on foreign class
|
||||
- remember receiver in slot zero
|
||||
- freeing:
|
||||
- memory for foreign objects managed like all mem in wren
|
||||
- may be gc'd
|
||||
- usually ok
|
||||
- but foreign obj may point to resource whose lifetime should be tied to
|
||||
life of obj
|
||||
- for ex: file handle
|
||||
- if foreign obj is collected, no longer have way to get to file handle
|
||||
- if didn't close it first, leak
|
||||
- when object is gc'd, want to close file
|
||||
- define finalizer fn
|
||||
- other thing set in bindForeignClassFn
|
||||
- if provided, gc calls this before obj is collected
|
||||
- provides raw bits of obj
|
||||
- nothing else!
|
||||
- called from right inside gc, so vm is in brittle state
|
||||
- don't mess with wren, use stack, etc.
|
||||
- just free resource
|
||||
- cannot fail
|
||||
|
||||
Until these are written, you can read the docs in [wren.h][].
|
||||
|
||||
|
||||
@ -17,9 +17,9 @@ around with Wren objects from C, you do so by going through an array of slots.
|
||||
You can think of it as a shared message board that both the VM and your C code
|
||||
can leave bits of data on for the other side to process.
|
||||
|
||||
The array is zero-based, and each slot holds a value of any type. It is
|
||||
dynamically sized, but it's your responsibility to ensure there are enough
|
||||
slots *before* you use them. You do this by calling:
|
||||
The array is zero-based, and each slot can hold a value of any type. It is
|
||||
dynamically sized, but it's your responsibility to ensure there are enough slots
|
||||
*before* you use them. You do this by calling:
|
||||
|
||||
:::c
|
||||
wrenEnsureSlots(WrenVM* vm, int slotCount);
|
||||
@ -126,7 +126,7 @@ can ask:
|
||||
WrenType wrenGetSlotType(WrenVM* vm, int slot);
|
||||
|
||||
This returns an enum defining what type of value is in the slot. It only covers
|
||||
the primitive values that are supported by the C API. Thinks like ranges and
|
||||
the primitive values that are supported by the C API. Things like ranges and
|
||||
instances of classes come back as `WREN_TYPE_UNKNOWN`. If you want to move that
|
||||
kind of data between Wren and C, you'll have to pull the object apart into
|
||||
simple primitive values first or use a [foreign class][].
|
||||
|
||||
Reference in New Issue
Block a user