Skip to content

[WIP] snapshot feature (issue 535) + many tiny changes #1196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 272 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
272 commits
Select commit Hold shift + click to select a range
bfe57f4
src/vm/wren_core.wren*: TakeSequence: new(): document the 3rd instanc…
Oct 22, 2024
44e6532
src/vm/wren_debug.c: dumpInstruction(): CODE_CLOSURE: handle spaces b…
Oct 23, 2024
c15339e
src/vm/wren_debug.c: dumpInstruction(): use local variable `code`
Oct 23, 2024
ca35192
src/vm/wren_debug.c: dumpInstruction(): END, END_MODULE: layout as si…
Oct 23, 2024
253011c
src/vm/wren_debug.c: dumpInstruction(): #undef BYTE_INSTRUCTION
Oct 23, 2024
57b55b2
src/vm/wren_debug.c: dumpInstruction(): fix typo when yelling at a ba…
Feb 11, 2025
be4805b
src/vm/wren_compiler.c: wrenCompile(): numExistingVariables: constify…
Oct 23, 2024
eee4816
src/vm/wren_opcodes.h: doc: remove CODE_ prefix
Oct 23, 2024
4c375e3
src/vm/wren_opcodes.h: doc: STORE and LOAD are prefixes, not suffixes
Oct 23, 2024
e8d7224
src/vm/wren_opcodes.h: doc: add notes
Oct 23, 2024
08c62e0
src/vm/wren_opcodes.h: doc: AND, OR: improve wording
Oct 23, 2024
f5c3c3f
src/vm/wren_vm.c: include standard header files first
Oct 24, 2024
4128872
src/vm/wren_primitive.c: include standard header file first
Oct 24, 2024
78fa9a2
test/main.c: include standard header files first
Oct 28, 2024
1184b51
test/test.c: tune comments to create sections
Nov 20, 2024
835c856
src/vm/wren_value.h: insert comments to create sections
Dec 6, 2024
d07766d
src/vm/wren_value.c: insert comments to create sections
Nov 5, 2024
c44fc6c
src/vm/wren_common.h: insert comments to create sections
Nov 8, 2024
243be2e
src/vm/wren_core.c: insert comments to create sections
Dec 4, 2024
44c06eb
src/vm/wren_core.c: fix spacing
Jan 20, 2025
282b296
src/vm/wren_core.c: runFiber(): improve doc
Feb 18, 2025
5931839
src/vm/wren_primitive.h: doc: fix name of function-like args
Oct 24, 2024
7b0cf1f
src/vm/wren_vm.c: wrenCollectGarbage(): print delta as a signed value
Oct 28, 2024
31583aa
test/limit/too_many_constants.wren: fix typo in number
Oct 30, 2024
f0ee2be
src/vm/wren_vm.h: improve doc
Nov 5, 2024
d99d5d5
src/vm/wren_vm.h: wrenGetClassInline(): better break in switch
Feb 11, 2025
5c6ce3c
src/vm/wren_vm.h: wrenGetClassInline(): move misplaced #if WREN_NAN_T…
Feb 11, 2025
e599e75
src/vm/wren_core.h: improve doc
Nov 5, 2024
f470805
src/vm/wren_vm.c: remind the WREN_COMPUTED_GOTO condition on #else an…
Jan 21, 2025
13a67e4
src/vm/wren_value.h: remind the WREN_NAN_TAGGING condition on #else a…
Dec 6, 2024
a97b3ea
src/vm/wren_value.h: doc: fix typos
Nov 5, 2024
b21d53c
src/vm/wren_value.h: struct sObjFiber: caller: improve doc
Jan 21, 2025
c5014c4
src/vm/wren_value.h: improve doc about NaN tagging
Feb 11, 2025
c1dec31
src/vm/wren_value.c: initObj(): doc
Nov 22, 2024
2c09da9
src/vm/wren_value.c: wrenNewModule(): access the `obj` member in a ge…
Jan 7, 2025
9840f02
src/vm/wren_value.c: wrenNewClosure(): clearer comment
Nov 29, 2024
66a11fe
src/vm/wren_value.c: wrenGrayBuffer(): rename function as wrenGrayVal…
Dec 12, 2024
0bcf5b6
DEFINE_BUFFER() needs no ';'
Nov 29, 2024
77df951
src/vm/wren_vm.c: fix indent and spacing
Dec 3, 2024
117d67b
src/vm/wren_vm.c: importModule(): remove unused variable
Jan 17, 2025
26d7aa6
src/vm/wren_vm.c: runtimeError(): use more the existing local variables
Jan 21, 2025
b646531
src/vm/wren_vm.c: runInterpreter(): RUNTIME_ERROR(): use more the exi…
Jan 21, 2025
f5e16e5
src/vm/wren_vm.c: METHOD_FUNCTION_CALL: fix code style
Jan 21, 2025
0ee2ae4
util/metrics.py: clean up cruft
Jan 10, 2025
f7166eb
util/metrics.py: order the counts the same, and line them up vertically
Jan 10, 2025
fb87e55
util/metrics.py: show the programming language
Jan 10, 2025
69b2d46
util/metrics.py: rework FORMAT_LINE
Jan 10, 2025
5704fb1
util/metrics.py: compile EOL_PATTERN
Jan 10, 2025
7e643fc
util/test.py: don't repeat maximum duration in comment
Dec 13, 2024
702692a
util/test.py: group patterns
Dec 13, 2024
f226e09
util/test.py: remove old cruft
Jan 24, 2025
68544d2
util/test.py: explain the command line options
Jan 24, 2025
af6f841
util/test.py: add --verbose option
Jan 24, 2025
a1ecb10
util/test.py: add --myself option for verifying the test runner itself
Jan 24, 2025
6bb0460
util/test.py: improve how problems are shown
Jan 24, 2025
dcc7e6c
util/test.py: also stderr benefits from removing the trailing last em…
Jan 24, 2025
40c2e31
util/test.py: handle no runtime error after skipping 2 lines of compi…
Jan 29, 2025
593f637
util/test.py: rename variables to avoid confusing line content VS lin…
Jan 29, 2025
6f98fb2
wrenFindVariable(): remove unused WrenVM parameter
Jan 20, 2025
ad0ec2c
wrenAppendCallFrame(): comment out unused WrenVM parameter
Jan 20, 2025
17f6d04
wrenListIndexOf(): comment out unused WrenVM parameter
Jan 20, 2025
fdc057a
meta module: wrenMetaBindForeignMethod(): comment out unused WrenVM p…
Jan 20, 2025
0a27e39
random module: wrenRandomBindForeign*(): comment out unused parameters
Jan 20, 2025
2c594f5
src/vm/wren_compiler.c: declareMethod(): comment out unused int param…
Jan 20, 2025
a4b832d
src/vm/wren_vm.c: createForeign(): comment out unused ObjFiber parameter
Jan 20, 2025
b8e8076
src/vm/wren_vm.c: runInterpreter(): a Method closure is an ObjClosure
Jan 20, 2025
50799c6
src/vm/wren_vm.c: runInterpreter(): #undef all the function-specific …
Jan 20, 2025
b708c68
src/vm/wren_vm.c: bindMethod(): prefer a bool isStatic parameter
Jan 21, 2025
ce191f1
src/vm/wren_vm.c: RUNTIME_ERROR(): improve doc
Jan 21, 2025
a9a1dfa
src/vm/wren_vm.c: reorder specifiers
Jan 21, 2025
d090354
src/vm/wren_vm.c: style ASSERT() better
Jan 22, 2025
e2d6bd5
src/vm/wren_vm.c: wrenCall(): improve ASSERT messages
Jan 22, 2025
aa1ffa6
src/vm/wren_vm.c: runInterpreter(): PEEK() and PEEK2(): use array not…
Feb 18, 2025
7b12f2c
src/vm/wren_vm.c: captureUpvalue(), closeUpvalues(): improve doc
Feb 18, 2025
4b2c027
src/vm/wren_vm.c: wrenNewVM(): fix coding style
Feb 18, 2025
2fda313
test/test.c: reorder specifiers
Jan 21, 2025
b7f8d4d
example/mandelbrot.wren: improve
Feb 6, 2025
10b0667
test/language/logical_operator/*_truth.wren: minimize diff between th…
Feb 11, 2025
9f0c907
test/language/logical_operator/{or,and}.wren: improve
Feb 11, 2025
42913e4
TREEWIDE: wrenPopRoot(): always annotate, unless obvious after an `if`
Feb 11, 2025
cde3f75
src/vm/wren_compiler.c: addToAttributeGroup(): pop in reverse order
Feb 11, 2025
17bf1a7
src/vm/wren_utils.c: wrenSymbolTableAdd(): wrenPushRoot(): upcast via…
Feb 11, 2025
b53b8cd
Add a patch to easily skip tests which are long when WREN_DEBUG_GC_ST…
Mar 12, 2025
c83eb1e
When transferring away from a fiber, close all its upvalues
Mar 12, 2025
e423cf8
Doxyfile: template
Oct 30, 2024
5aff0b1
Doxyfile: tune to Wren project
Nov 5, 2024
cee552a
[TOIMPROVE] example/syntax.wren: exhibit all operators
Nov 5, 2024
0cdec59
[TOIMPROVE] src/vm/wren_core.c: DEF_NUM_CONSTANT(): fix doc
Nov 5, 2024
4a59755
[TOIMPROVE] src/vm/wren_opcodes.h: wording to improve???
Nov 5, 2024
422a7ee
src/vm/wren_vm.c: wrenInterpret(): split into wrenCompileSourceLines(…
Oct 24, 2024
19bd492
[API]: allow to separate phase of compilation into bytecode, then int…
Oct 24, 2024
dac4413
[TOREORDER earlier] src/vm/wren_value.h: document inheritance for Dox…
Dec 16, 2024
aefaa80
test/test.c: runCode(): extract function
Oct 30, 2024
32367b0
test/test.c: runCode(): move earlier in the file
Nov 5, 2024
9a1d06d
[TOVERIFY] test/test.c: use the 2-step API
Nov 5, 2024
db46d19
[TRY] visit objects after compilation
Nov 5, 2024
ffde4a0
[TRY] test/test.c: (commented-out) manage a bytecode file
Nov 5, 2024
2a0684a
[TRY] src/vm/wren_value.c: (commented-out) verbose marking of objects…
Nov 5, 2024
dcd53e0
[TOIMPROVE] src/vm/wren_debug.c: enhance dumping
Nov 5, 2024
341cc25
[Quick&Dirty] src/vm/wren_vm.*: manage a bytecodeFile
Nov 5, 2024
160fce5
[Quick&Dirty] src/vm/wren_debug.*: save bytecode
Nov 5, 2024
58438a3
[Q&D]: src/vm/wren_debug.c: dump name of function
Nov 5, 2024
a38c41e
src/vm/wren_value.c: handle visiting a map
Nov 5, 2024
7bf0032
src/vm/wren_value.c: handle visiting a module
Nov 5, 2024
f9ffa3a
[TRY] countAllObj()
Nov 6, 2024
1453eaa
[TRY]: countAllObj() returns struct wrenCountObj
Nov 6, 2024
ba3de22
[TRY] censusObj()
Nov 6, 2024
6b74b66
[TRY] censusObj(): do all Obj types
Nov 6, 2024
120da89
[TRY] wrenCountObj: expand to uint64_t
Nov 7, 2024
bc19dd1
pass wrenCountObj as an in/out param via a pointer
Nov 7, 2024
20b4e49
wrenCountObj: move `nb` at the end of struct
Nov 7, 2024
3da19b4
rename struct: s/wrenCountObj/WrenCounts/
Nov 7, 2024
b965691
rename function: s/countAllObj/wrenCountAllObj/
Nov 7, 2024
22e20a8
rename function: s/censusObj/wrenCensusAllObj/
Nov 7, 2024
310dfa5
new struct WrenCensus
Nov 7, 2024
f9f36d1
[FIXUP] src/vm/wren_vm.c: use ALLOCATE_ARRAY and DEALLOCATE
Nov 8, 2024
b320548
[FIXUP] with uint64_t
Nov 7, 2024
ccfdec1
wrenFindInCensus(): new function
Nov 7, 2024
8fe3f0a
typedef uint64_t WrenCount
Nov 8, 2024
eca8fa9
Introduce #define WREN_SNAPSHOT
Nov 8, 2024
77fa983
wrenFindInCensus(): doc the function; offset its returned value
Nov 13, 2024
fdae6a0
new feature (in progress): saving a snapshot of the VM
Nov 13, 2024
aa417c4
src/vm/wren_debug.c: factor out `verbose` bool variable
Nov 14, 2024
2592ff7
src/vm/wren_debug.c: saveOneString(): extract function
Nov 14, 2024
54d9149
src/vm/wren_debug.c: saveOneModule(): extract function
Nov 14, 2024
85ab8f6
src/vm/wren_debug.c: SAVE_ALL(): extract macro
Nov 14, 2024
4926790
src/vm/wren_debug.c: saveAllString(): generate it with SAVE_ALL() macro
Nov 14, 2024
d386321
src/vm/wren_debug.c: SAVE_ALL(): verbosely show the count nicer
Nov 14, 2024
556a753
snapshot: save ObjFn
Nov 15, 2024
3cea767
snapshot: save ObjClosure
Nov 15, 2024
8ad1cf6
src/vm/wren_debug.c: saveValue(): extract function
Nov 15, 2024
149d838
src/vm/wren_debug.c: saveValue(): handle singleton values
Nov 15, 2024
a7481d2
snapshot: save ObjMap
Nov 15, 2024
e259946
src/vm/wren_debug.c: saveValue(): handle when no WREN_NAN_TAGGING
Nov 15, 2024
c5379f2
wrenFindInCensus(): handle needle being NULL
Nov 19, 2024
5756be0
snapshot: save ObjClass
Nov 19, 2024
02694fa
s/saveOneFOO/saveObjFOO/
Nov 19, 2024
180eec6
snapshot: an enum for ValueTypeChar
Nov 19, 2024
e148381
snapshot: saveVM()
Nov 19, 2024
fe16900
src/vm/wren_debug.c: #undef SAVE_ALL
Nov 20, 2024
dc82ac8
wrenSaveCode(): remove function
Nov 19, 2024
bb23748
snapshot: move macros at a better place in the source file
Nov 19, 2024
a86bc44
src/vm/wren_vm.c: performCount(): extract function
Nov 21, 2024
e8cc14f
Shorten lifetime of FILE into which is saved a snapshot
Nov 21, 2024
091d920
src/vm/wren_vm.c: createCoreObj(): extract function
Nov 21, 2024
618130b
wrenNewVM(): split into wrenNewEmptyVM() and createCoreObj()
Nov 21, 2024
83ec259
snapshot: introduce typedef ObjOrValueType
Nov 26, 2024
cf8b8d0
src/vm/wren_debug.c: allow the sourceLines IntBuffer to be empty
Nov 29, 2024
c5ab039
[WIP] saveObjModule(): doc that core module has no name
Nov 29, 2024
47b79e7
[WIP] saveObjFn(): add TODO fn->maxSlots
Nov 29, 2024
6f9519e
[WIP] saveObjFn(): commented-out sourceLinesCount
Nov 29, 2024
2e26a2e
[WIP] [BIG] Snapshot restore
Nov 29, 2024
e1afaac
f wrenVisitObjects(): comment #endif
Dec 12, 2024
5a654c8
restore ObjClosure
Nov 29, 2024
a8d8ee2
snapshot restore: detect when referring to an Obj ID not yet restored
Dec 2, 2024
82ae722
restore ObjMap
Dec 2, 2024
1de5b55
restore ObjClass
Dec 3, 2024
2f49eba
snapshot: restore VM
Dec 3, 2024
2d1c005
wrenCensusAllObj(): store objects from oldest to youngest
Dec 4, 2024
14cba7f
snapshot: restore superclass too
Dec 5, 2024
7a3d378
snapshot: save and restore primitives
Dec 5, 2024
592cd07
src/vm/wren_utils.h: extract function wrenFOOBufferEnsure()
Dec 5, 2024
d84a51b
snapshot restore: ensure size of buffer before restoring its content
Dec 5, 2024
92366e2
snapshot restore: record the swizzle operations to be done later
Dec 6, 2024
2bb4b9f
snapshot restore: swizzle the pointers
Dec 6, 2024
3bba680
snapshot: handle metaclass
Dec 6, 2024
5a834f0
f on [WIP] [BIG] Snapshot restore
Dec 13, 2024
37e6c23
snapshot: handle the entrypoint
Dec 9, 2024
e93483f
snapshot: run the restored code
Dec 9, 2024
f695b61
f run snapshot restore
Dec 12, 2024
081ef94
snapshot: export restore functions as API
Dec 9, 2024
85e61eb
src/vm/wren_debug.c: restoreByteBuffer(): restore directly in the buffer
Dec 10, 2024
d28e24f
snapshot restore: ASSERT() is better than buffer overflow
Dec 10, 2024
534aae4
snapshot: #if WREN_SNAPSHOT
Dec 12, 2024
3beaf50
snapshot restore: WrenSnapshotReadFn: abstract away from FILE*
Dec 16, 2024
92611f6
[BAD MIX] restore snapshot from memory
Dec 20, 2024
94d14f8
shrink WrenCount from 64 to 32 bits
Dec 20, 2024
f70e03f
embedded bytecode: now 32-bit and const
Jan 8, 2025
a6dba58
enable back slurping a file, now better named `bytecode-to-restore.bin`
Jan 8, 2025
8c300ce
change snapshot format: an ObjClass has `numFields` just after `name`
Jan 8, 2025
c077ab8
restoreObjClass(): create class earlier
Jan 8, 2025
7b8d4e1
snapshot: use SymbolTable abstraction instead of bare StringBuffer
Jan 9, 2025
3ecce54
change snapshot format: save vm->methodNames just after all ObjString
Jan 9, 2025
2c6580d
nicer verbose snapshot
Jan 9, 2025
bc87b99
restoreObjFn(): dumping code now has the correct method names
Jan 9, 2025
cc5eea9
src/vm/wren_debug.c: saveValueBuffer(): define with new macro SAVE_BU…
Jan 9, 2025
a9b0a1f
src/vm/wren_debug.c: saveStringBuffer(): define with SAVE_BUFFER()
Jan 9, 2025
6736c9b
src/vm/wren_debug.c: saveMethodBuffer(): define with SAVE_BUFFER()
Jan 9, 2025
9861e96
restoreMethodBuffer(): define with new macro RESTORE_BUFFER()
Jan 9, 2025
59009f9
restoreStringBuffer(): define with RESTORE_BUFFER()
Jan 9, 2025
c250856
change snapshot format: handle FnDebug->sourceLines
Jan 9, 2025
c80f32c
snapshot: don't be verbose
Jan 13, 2025
6255d0d
snapshot: show errors in new VM, propagate errors
Jan 13, 2025
7ef61a6
snapshot: run in new VM only
Jan 13, 2025
14c06ca
snapshot restore: handle true and false values
Jan 14, 2025
1c984a8
restoreObjClass(): store attributes
Jan 14, 2025
3e2697f
snapshot save: saveVM(): use WrenSnapshotContext
Jan 16, 2025
6312490
saveMethodNames(): use WrenSnapshotContext
Jan 16, 2025
a96afe9
SAVE_ALL(): use WrenSnapshotContext
Jan 16, 2025
5fb6d39
saveObjFOO(): use WrenSnapshotContext
Jan 16, 2025
08866bd
saveSymbolTable(): use WrenSnapshotContext
Jan 16, 2025
8b6e8e5
saveByteBuffer(): use WrenSnapshotContext
Jan 16, 2025
cb101b8
SAVE_BUFFER(): use WrenSnapshotContext
Jan 16, 2025
49b4ff7
saveFOO(): use WrenSnapshotContext
Jan 16, 2025
7e5a0d4
snapshot: VERBOSE: avoid dangling else problem
Jan 16, 2025
f08c6a9
snapshot: fwrite(): fix confusion between {how many items} and {how l…
Jan 17, 2025
dbdb0cf
snapshot: saveObjFn(): nicer letters when verbose
Jan 17, 2025
e91660d
snapshot: WrenSnapshotContext: distinguish the struct from the typedef
Jan 17, 2025
2494f3f
swizzlePointers(): if ASSERT() does nothing, better init the pointer …
Jan 17, 2025
073b614
snapshot: restoreValue() needn't WrenVM parameter
Jan 17, 2025
4411de6
[TODEL] snapshot: wrenVisitObjects(): return something even when no W…
Jan 21, 2025
b71225d
snapshot: assertCanSaveSnapshot(): new function
Jan 22, 2025
1fd27f2
f [TOSQUASH] DO(): line up on 80th column
Jan 22, 2025
3400737
snapshot restore: copy module-related functions from the existing VM
Jan 27, 2025
04f5a51
snapshot save: use a new WrenSnapshotWriteFn
Jan 28, 2025
3bcc3ca
snapshot restore: avoid wrenDumpCode() when any swizzle is found
Jan 31, 2025
548a68d
restoreValue(): factor out RETURN_ID_AS_OBJ()
Jan 31, 2025
99ee28f
restoreValue(): nicer formatting + scope improvement
Jan 31, 2025
7263b47
snapshot save: saveNum(), saveObj(): extract functions
Feb 12, 2025
80b222e
snapshot restore: new field WrenSnapshotContext::priv, which can be W…
Feb 12, 2025
1f115f9
snapshot restore: readFromFILE() which uses WrenSnapshotContext::priv
Feb 13, 2025
fe72bcb
snapshot save: writeToFILE() which uses WrenSnapshotContext::priv
Feb 13, 2025
d717a8d
snapshot restore: kill buf_read()
Feb 13, 2025
bb51b54
snapshot: kill WrenSnapshotContext::file
Feb 13, 2025
32bf055
snapshot: tweak struct sWrenSnapshotContext
Feb 13, 2025
d9736d5
snapshot: WrenSnapshotContext: s/priv/stream/
Feb 13, 2025
d0672fe
[FIXUP] snapshot: style on comment about wrenPopRoot()
Feb 27, 2025
a51ac04
[FIXUP] snapshot: struct initializer must be non-empty
Feb 27, 2025
48cba3f
[FIXUP] snapshot: drop redundant #if, already enforced
Feb 27, 2025
f074aff
snapshot: allow run-time behavior via environment variables
Feb 27, 2025
e0d8938
snapshot restore: DRY WrenSnapshotContext content
Feb 28, 2025
ee09ad8
snapshot: the verbosity is now runtime and per-context
Mar 3, 2025
868d61d
snapshot: prepend a magic value and a version
Mar 4, 2025
67d7832
snapshot: implement options: withSourceLines
Mar 5, 2025
819e80f
snapshot: new option: withFnNames
Mar 6, 2025
a2b742f
snapshot: verbose is now an option
Mar 6, 2025
c2bdbbe
snapshot: inhibit GC while a snapshot happens
Mar 12, 2025
af2e518
snapshot: saveIdOfObj(): extract function
Mar 11, 2025
af253e1
snapshot: new option to shorten ids (but not yet effective)
Mar 11, 2025
0508176
snapshot: use possibly-shortened ids
Mar 12, 2025
b9f54e2
src/vm/wren_utils.[ch]: wrenSymbolTableAppend(): extract function
Feb 3, 2025
60002a0
wrenDefineVariable(): allow to reuse an existing ObjString
Feb 3, 2025
25429dc
snapshot: fix braino when verifying wrenSnapshotMagic
Mar 13, 2025
98d2562
snapshot: add TODOs
Mar 13, 2025
b30bb75
snapshot: wrenFreeVM(): reinstate the barrier
Mar 13, 2025
188d38d
snapshot: wrenSnapshotWant(): better doc dependencies of possibilities
Mar 13, 2025
0f0711c
snapshot: add an example of embedding
Mar 13, 2025
fe8b16f
example/embedding/snapshot/.gitignore: new file
Mar 13, 2025
eb1f340
snapshot: add note whether the caller should have a handle on the clo…
Mar 13, 2025
0b67d22
doc/notes/snapshot.md: new file
Mar 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ ipch/

# macOS
.DS_Store

# Doxygen
/doxygen/
2,658 changes: 2,658 additions & 0 deletions Doxyfile

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions doc/notes/snapshot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
## Save and restore a snapshot of a Wren VM

NOTE: still in flux!

### Identify an Obj independently...

That's *pointer unswizzling*.

#### ... from a bare C pointer

References as pointers are everywhere, but we need to identify an Obj.

#### ... from the order of the linked list of all Obj

Iterating on the singly-linked list of all Obj from `vm->first`.
When saving an existing VM, we iterate them from the most recently created to the oldest created (e.g. the Object class).
When restoring a snapshot, the first item read, which was the most recently created, is now created first, and will become the oldest created.



### Census

The VM must be paused.
It's related to a VM, yet it has no pointer to it.

GC is forbidden meanwhile saving/restoring
nothing is hold!



Can now fork a VM :-)
Conceptually extensible to a full hibernation/thaw



The serialization file format is underspecified.
Upon de-serialization, not enough tests are done.
[KINDS-OF-DOC]: https://github.com/munificent/craftinginterpreters/blob/master/note/design%20breaks.md
Values of enum ObjType are reused as is, thus no longer changeable.




# Safety

ALLOCATE is expected to succeed. (As elsewhere in the WrenVM.)



# TODO Security

A fuzzy snapshot is an art better suited to museums than computer science. :-)

what if restoring 0 ObjFOO? Does ALLOCATE work?

what if ObjFn#9 references:
- ObjFn#1000?
- itself?

vm->modules must be a Map from ObjString to ObjModule

mkdir test/snapshot/restore/bad...


When restoring, an absent `fn->debug->name` could be synthesized as `fn0`

Validate bytecode
- opcodes are known
- opcode arg is valid WRT constants count
- all jumps land on an instruction start
- ...




## Unit tests

hijacked^Wenhanced test/test.c

all but 5 tests pass
- you must preserve line numbers (with the '1' char), otherwise many sadness, such as:
> FAIL: test/limit/too_many_inherited_fields.wren
> Expected runtime error on line 139 but was on line 0.
- The 5 failing tests are the ones of APITest_Run()
- they use the VM after its initialization, but the transient VM is not a replacement of the tested one.



# TODO

# should re-shuffle code

src/snapshot/count.c
src/snapshot/types.h
src/snapshot/save.h
src/snapshot/restore.h

## easy, but require to unmark static or re-shuffle code

String restore
Map resize


TODO:
- TAG_NAN saved when WREN_NAN_TAGGING can't be restored in a VM without WREN_NAN_TAGGING.

dedup strings more

dedup other?
CONST_STRING should memoize
sizeof(sObj) is 32; CAN shrink
NOT fool-proof
src/vm/wren_vm.c:533
bindMethod() should IS_CLOSURE()
RLE for:
- empty methods
- debugLines

what if many local vars on top-level?

CHAR(oneCharStr) should be CHAR(c)

in src/vm/wren_vm.c, should wrenCollectGarbage() gray the 11 vm->FOOclass?
no



# FlatBuffers in C, flatcc

need a lib?
it adds padding.
must hook its allocation to ALLOCATE()

[]: https://flatbuffers.dev/md__internals.html
> scalars of various sizes, all aligned to their own size

> Strings are simply a vector of bytes, and are always null-terminated.
2 changes: 1 addition & 1 deletion doc/site/classes.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ You're saying "look up the method `isFancy` in the scope of the object
the object to the left of the period is the object you want to look up the
method on.

### `this`
### Using `this`

Things get more interesting when you're inside the body of a method. When the
method is called on some object and the body is being executed, you often need
Expand Down
2 changes: 1 addition & 1 deletion doc/site/contributing.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ server from there. Python includes one:
$ python -m http.server

Running that script every time you change a line of Markdown can be slow,
so there is also a file watching version that will automatically regenerate the
so there is also a file-watching version that will automatically regenerate the
docs when you edit a file:

$ python util/generate_docs.py --watch
Expand Down
4 changes: 2 additions & 2 deletions doc/site/embedding/calling-c-from-wren.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ flavor into our VM:
Since Wren is object-oriented, behavior lives in methods, so for the former we
have **foreign methods**. Likewise, data lives in objects, so for the latter, we
define **foreign classes**. This page is about the first, foreign methods. The
[next page][] covers foreign classes.
[next section][] covers foreign classes.

[next page]: /embedding/storing-c-data.html
[next section]: /embedding/storing-c-data.html

A foreign method looks to Wren like a regular method. It is defined on a Wren
class, it has a name and signature, and calls to it are dynamically dispatched.
Expand Down
4 changes: 2 additions & 2 deletions doc/site/embedding/calling-wren-from-c.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ arguments.

This is just a regular WrenHandle, which means you can hold onto it as long as
you like. Typically, you'd call this once outside of your application's
performance critical loops and reuse it as long as you need. It is us up to you
performance critical loops and reuse it as long as you need. It is up to you
to release it when you no longer need it by calling `wrenReleaseHandle()`.

## Setting Up a Receiver
Expand Down Expand Up @@ -173,7 +173,7 @@ keeps running until either the method returns or a fiber [suspends][].

[suspends]: ../modules/core/fiber.html#fiber.suspend()

`wrenCall()` returns the same WrenInterpretResult enum as `wrenInterpret()` to
`wrenCall()` returns the same `WrenInterpretResult` enum as `wrenInterpret()` to
tell you if the method completed successfully or a runtime error occurred.
(`wrenCall()` never returns `WREN_ERROR_COMPILE` since it doesn't compile
anything.)
Expand Down
40 changes: 20 additions & 20 deletions doc/site/embedding/configuring-the-vm.markdown
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
^title Configuring the VM

When you create a Wren VM, you tweak it by passing in a pointer to a
WrenConfiguration structure. Since Wren has no global state, you can configure
`WrenConfiguration` structure. Since Wren has no global state, you can configure
each VM differently if your application happens to run multiple.

The struct looks like:
Expand Down Expand Up @@ -29,15 +29,15 @@ wrenInitConfiguration(&configuration);
</pre>

Calling this ensures that your VM doesn't get uninitialized configuration when
new fields are added to WrenConfiguration. Here is what each field does, roughly
new fields are added to `WrenConfiguration`. Here is what each field does, roughly
categorized:

## Binding

The VM is isolated from the outside world. These callbacks let the VM request
access to imported code and foreign functionality.

### **`loadModuleFn`**
### The **`loadModuleFn`** callback

This is the callback Wren uses to load an imported module. The VM itself does
not know how to talk to the file system, so when an `import` statement is
Expand All @@ -56,12 +56,12 @@ host should return the source code for that module in a `WrenLoadModuleResult` s
<pre class="snippet" data-lang="c">
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
result.source = getSourceForModule(name);
result.source = getSourceForModule(name);
return result;
}
</pre>

The module loader is only be called once for any given module name. Wren caches
The module loader is only called once for any given module name. Wren caches
the result internally so subsequent imports of the same module use the
previously loaded code.

Expand All @@ -80,7 +80,7 @@ static void loadModuleComplete(WrenVM* vm,
const char* module,
WrenLoadModuleResult result)
{
if(result.source) {
if (result.source) {
//for example, if we used malloc to allocate
//our source string, we use free to release it.
free((void*)result.source);
Expand All @@ -89,23 +89,23 @@ static void loadModuleComplete(WrenVM* vm,

WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
result.onComplete = loadModuleComplete;
result.source = getSourceForModule(name);
result.onComplete = loadModuleComplete;
result.source = getSourceForModule(name);
return result;
}
</pre>

### **`bindForeignMethodFn`**
### The **`bindForeignMethodFn`** callback

The callback Wren uses to find a foreign method and bind it to a class. See
This is the callback Wren uses to find a foreign method and bind it to a class. See
[this page][foreign method] for details. If your application defines no foreign
methods, you can leave this `NULL`.

[foreign method]: /embedding/calling-c-from-wren.html

### **`bindForeignClassFn`**
### The **`bindForeignClassFn`** callback

The callback Wren uses to find a foreign class and get its foreign methods. See
This is the callback Wren uses to find a foreign class and get its foreign methods. See
[this page][foreign class] for details. If your application defines no foreign
classes, you can leave this `NULL`.

Expand All @@ -116,11 +116,11 @@ classes, you can leave this `NULL`.
These let you wire up some minimal output so you can tell if your code is doing
what you expect.

### **`writeFn`**
### The **`writeFn`** callback

This is the callback Wren uses to output text when `System.print()` or the other
related functions are called. This is the minimal connection the VM has with the
outside world and lets you do rudimentary "printf debugging". Its signature is:
outside world and lets you do rudimentary "`printf()` debugging". Its signature is:

<pre class="snippet" data-lang="c">
void write(WrenVM* vm, const char* text)
Expand All @@ -130,7 +130,7 @@ Wren does *not* have a default implementation for this. It's up to you to wire
it up to `printf()` or some other way to show the text. If you leave it `NULL`,
calls to `System.print()` and others silently do nothing.

### **`errorFn`**
### The **`errorFn`** callback

Wren uses this callback to report compile time and runtime errors. Its signature
is:
Expand Down Expand Up @@ -177,7 +177,7 @@ If you leave this `NULL`, Wren does not report any errors.

These fields control how the VM allocates and manages memory.

### **`reallocateFn`**
### The **`reallocateFn`** callback

This lets you provide a custom memory allocation function. Its signature is:

Expand All @@ -195,9 +195,9 @@ freed, this is zero. Your callback should allocate the proper amount of memory
and return it.

If you don't provide a custom allocator, the VM uses a default one that relies
on `realloc` and `free`.
on `realloc()` and `free()`.

### **`initialHeapSize`**
### The **`initialHeapSize`** field

This defines the total number of bytes of memory the VM will allocate before
triggering the first garbage collection. Setting this to a smaller number
Expand All @@ -206,7 +206,7 @@ to collect garbage more frequently.

If you set this to zero, Wren uses a default size of 10MB.

### **`minHeapSize`**
### The **`minHeapSize`** field

After a garbage collection occurs, the threshold for the *next* collection is
determined based on the number of bytes remaining in use. This allows Wren to
Expand All @@ -219,7 +219,7 @@ back to a usable size.

If zero, this defaults to 1MB.

### **`heapGrowthPercent`**
### The **`heapGrowthPercent`** field

Wren tunes the rate of garbage collection based on how much memory is still in
use after a collection. This number controls that. It determines the amount of
Expand Down
10 changes: 5 additions & 5 deletions doc/site/embedding/index.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ virtual machine. To do that, you create a `WrenConfiguration` object and
initialize it.

<pre class="snippet" data-lang="c">
WrenConfiguration config;
wrenInitConfiguration(&config);
WrenConfiguration config;
wrenInitConfiguration(&config);
</pre>

This gives you a basic configuration that has reasonable defaults for
Expand All @@ -129,7 +129,7 @@ And then, we update the configuration to point to it.
<pre class="snippet" data-lang="c">
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.writeFn = &writeFn;
</pre>

[configuration]: configuring-the-vm.html
Expand Down Expand Up @@ -242,8 +242,8 @@ int main()

WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.writeFn = &writeFn;
config.errorFn = &errorFn;
WrenVM* vm = wrenNewVM(&config);

const char* module = "main";
Expand Down
2 changes: 1 addition & 1 deletion doc/site/embedding/slots-and-handles.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dynamically sized, but it's your responsibility to ensure there are enough slots
*before* you use them. You do this by calling:

<pre class="snippet" data-lang="c">
wrenEnsureSlots(WrenVM* vm, int slotCount);
void wrenEnsureSlots(WrenVM* vm, int numSlots);
</pre>

This grows the slot array if needed to ensure that many slots are available. If
Expand Down
Loading