mirror of
https://github.com/fluffos/fluffos
synced 2026-08-12 18:26:06 -04:00
* docs: add local full-text search and a contributor README Add @easyops-cn/docusaurus-search-local to the Docusaurus site so the docs get an offline search bar (index built at build time, no external service). English and zh-CN pages are both indexed, and matched terms are highlighted on the target page. Add docs/README.md describing the Docusaurus setup, local dev/build commands, search behavior, directory layout, and gotchas; exclude it from the published site alongside CLAUDE.md. Point the root README's docs/ entry at it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE * docs: remove dead framework leftovers, fix index generation, complete the nav Delete the VitePress (.vitepress/) and Jekyll (_layouts/, css/) leftovers, the one-shot migration scripts (fix_md_header.py, fix_seealso.py), and the stale keywords.json snapshot; prune the matching .gitignore entries and docusaurus exclude patterns. Rewrite gen_index.py for Docusaurus: it emitted dead .html links and legacy 'layout: doc' frontmatter, choked on non-markdown entries, and dropped nested categories — regenerating an index would have broken it. It now emits the extension-less links the site actually uses, links nested category indexes (restoring apply/* on the zh-CN index), and refuses to run on the docs root. Fix update_index.sh's copy-paste titles (zh-CN efun/build were titled 'APPLY'), stop it clobbering the hand-written lpc/index.md, and cover cli/. Regenerated indexes pick up the missing driver/ffi-plan entry. add_missing_efuns.py now takes the keywords.json path as an argument instead of requiring a stale copy. Move CNAME and the Google site-verification file into static/ so they actually reach the published build output. Complete the sidebar: link the CLI category to cli/index and add the missing portbind/symbol/generate_keywords pages, and expose the previously orphaned stdlib section under Reference. Promote onBrokenLinks to 'throw' now the build is warning-free, and drop the empty Demo section from the landing page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE * docs: strip legacy 'layout: doc' frontmatter from all pages Mechanical sweep removing the Jekyll-era 'layout: doc' line from every doc page's frontmatter (Docusaurus ignores it), and the matching line from the templates in docs/CLAUDE.md so new pages don't reintroduce it. No content changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE --------- Co-authored-by: Claude <noreply@anthropic.com>
156 lines
4.7 KiB
Markdown
156 lines
4.7 KiB
Markdown
---
|
|
title: general / stackmachine
|
|
---
|
|
# stackmachine
|
|
|
|
THIS IS A DOCUMENT THAT DESCRIBES HOW A VIRTUAL STACK MACHINE HAS BEEN DEFINED, TO EXECUTE COMPILED LPC CODE.
|
|
|
|
There are two stacks:
|
|
|
|
1. The stack of values, used for evaluation, local variables and arguments.
|
|
Note that arguments are treated as local variables. Every element on the
|
|
value stack will have the format `struct svalue`, as defined in `interpret.h`.
|
|
The value stack is stored in an array, with limited size. The first push
|
|
operation will store a value into element 0. Access of arguments and local
|
|
variables are supposed to be fast, by simply indexing in the value stack
|
|
using the frame pointer as offset.
|
|
|
|
```
|
|
Start of stack -----
|
|
|
|
|
Frame pointer-> | Argument number 0
|
|
| Argument number 1
|
|
| etc.
|
|
| Local variable number 0
|
|
| Local variable number 1
|
|
| etc.
|
|
| Temporary stack values
|
|
| etc
|
|
v
|
|
```
|
|
|
|
2. The control stack that contains return addresses, frame pointer etc.
|
|
|
|
## CALLING LOCAL FUNCTIONS.
|
|
|
|
All arguments are evaluated and pushed to the value stack. The last argument
|
|
is the last pushed. It is important that the called function gets exactly as
|
|
many arguments as it wants. The number of arguments will be stored in the
|
|
control stack, so that the return instruction not needs to know it
|
|
explicitly.
|
|
|
|
Instruction format:
|
|
|
|
```
|
|
b0 b1 b2 b3
|
|
|
|
b0 = F_FUNCTION.
|
|
b1, b2 = The number of the function to be called.
|
|
b3 = Number of arguments sent.
|
|
|
|
```
|
|
|
|
The `F_FUNCTION` instruction will also initiate the frame pointer to point
|
|
to the first argument.
|
|
|
|
The number of arguments are stored in the 'struct function' which is found
|
|
using the number of the function and indexing in `ob->prog->functions[]`;
|
|
The number of arguments will be adjusted to fit the called function.
|
|
This is done by either pushing zeroes, or poping excessive
|
|
arguments. `F_FUNCTION` will also initiate local variables, by pusing a 0
|
|
for each of them.
|
|
|
|
The called function must ensure that exactly one value remains on the
|
|
stack when returning. The caller is responsible of deallocating the
|
|
returned value.
|
|
|
|
When a function returns, it will use the instruction F_RETURN, which will
|
|
deallocate all arguments and local variables, and only let the top of stack
|
|
entry remain. The number of arguments and local variables are stored in the
|
|
control stack, so that the evaluator knows hoh much to deallocate.
|
|
|
|
If flag `extern_call` is set, then the evaluator should return. Otherwise,
|
|
the evaluator will continue to execute the instruction at the returned
|
|
address.
|
|
|
|
```
|
|
Format:
|
|
|
|
b0
|
|
|
|
b0 = F_RETURN.
|
|
```
|
|
|
|
## CALLING PREDEFINED FUNCTIONS.
|
|
|
|
Arguments are pushed to the stack. A value is always returned (on the stack).
|
|
|
|
Instruction format:
|
|
|
|
```
|
|
b1
|
|
|
|
b1 = The F\_ code of the called function.
|
|
```
|
|
|
|
If a variable number of arguments are allowed, then an extra byte will
|
|
follow the instruction, that states number of actual arguments.
|
|
|
|
The execution unit will parse number of arguments immediately, regardless
|
|
of which instruction it is when it is stated that a variable number of
|
|
arguments are allowed. It will also check soem of the types of the
|
|
arguments immediately, if it is possible. But never more than the types of
|
|
the first two arguments.
|
|
|
|
## F_SSCANF
|
|
|
|
The function sscanf is special, in that arguments are passed by reference.
|
|
This is done with a new type, T_LVALUE. The compiler will recognize
|
|
sscanf() as a special function, pass the value of the two first arguments
|
|
as normal rvalues and pass the rest as lvalues. The total number of arguments
|
|
is given as a one byte code supplied to the F_SSCANF instruction.
|
|
|
|
## F_CALL_OTHER
|
|
|
|
This command takes one argument, a byte which gives the number of arguments.
|
|
|
|
```
|
|
b1, b2
|
|
|
|
b1 = F_CALL_OTHER, b2 = number of arguments.
|
|
```
|
|
|
|
## F_AGGREGATE
|
|
|
|
This command takes one argument, the size of the array. The elements of
|
|
the array are picked from the top of stack.
|
|
|
|
```
|
|
b1, b2, b3
|
|
|
|
b1 = F_AGGREGATE, (b2,b3) = Size of the array (max 0xffff).
|
|
```
|
|
|
|
## F_CATCH
|
|
|
|
The compiler constructs a call to F_CATCH before the code to evaluate the
|
|
argument of F_CATCH. After the code, a call to F_RETURN is made. Thus,
|
|
it will look like a function call.
|
|
|
|
F_CATCH will when executed do setjmp() and call eval_instruction()
|
|
recursively. That means that a new frame has to be set up.
|
|
|
|
F_THROW will do a longjmp().
|
|
|
|
format:
|
|
|
|
```
|
|
F_THROW, b1, b2, (instructions...), F_RETURN
|
|
|
|
Where b1,b2 is the address of the instruction after the return instruction.
|
|
```
|
|
|
|
## F_RETURN
|
|
|
|
Will deallocate the current frame, and restore the previous. If the flag
|
|
extern_call is set, then a return from eval_instruction() will be done.
|