Merge branch 'master' of git@github.com:briantrice/slate-language
[cslatevm.git] / INTERNALS
blob08108b8495ca489c34b4e63fa369e4de12ca1816
1 Stack format / Calling convention
2 ---------------------------------
4 We are about to call a function.
5 fp at the time of the activation is equal to the current stack pointer plus the function frame size
6 (which is 6).
8 stack[fp-6] -> the stack pointer before the stack allocation for this frame + localvars + registers is done
9 stack[fp-5] -> the absolute stack position (stack location) of where the callee should place its result
10 stack[fp-4] -> the code pointer (ip) of the caller
11 stack[fp-3] -> the callee's closure/method
12 stack[fp-2] -> the callee's lexical context (nil for stack allocated frames)
13 stack[fp-1] -> frame pointer of caller
14 stack[fp+0] .. stack[fp+registerCount+lvCount] -> registers + local variables
16 When you return from a function and you want to restore the frame in
17 the interpreter object to what it was before the call, you restore
18 everything based on fp (interpreter's current fp) except the closure
19 and the lexical context which are restored based on the saved
20 framepointer (at fp-1) using the previous frame (notice callee
21 vs. caller).
24 basic overview (code summary):
26 function calling -- interpreter_apply_to_arity_with_optionals():
28   framePointer = i->stackPointer + FUNCTION_FRAME_SIZE;
29   /* store the old stack pointer so we know what to return it to after this function ends */
30   beforeCallStackPointer = i->stackPointer;
31   interpreter_stack_allocate(oh, i, FUNCTION_FRAME_SIZE /*frame size in words*/ + object_to_smallint(method->localVariables) + object_to_smallint(method->registerCount));
32   i->stack->elements[framePointer - 6] = smallint_to_object(beforeCallStackPointer);
33   i->stack->elements[framePointer - 5] = smallint_to_object(resultStackPointer);
34   i->stack->elements[framePointer - 4] = smallint_to_object(i->codePointer);
35   i->stack->elements[framePointer - 3] = (struct Object*) closure;
36   i->stack->elements[framePointer - 2] = (struct Object*) lexicalContext;
37   i->stack->elements[framePointer - 1] = smallint_to_object(i->framePointer);
38   i->framePointer = framePointer;
39   i->method = method;
40   i->closure = closure;
41   i->lexicalContext = lexicalContext;
44 function returning -- interpreter_return_result()
47   framePointer = i->framePointer;
48   resultStackPointer = (word_t)i->stack->elements[framePointer - 5]>>1;
49   i->stack->elements[resultStackPointer] = result;
50   i->stackPointer = object_to_smallint(i->stack->elements[framePointer - 6]);
51   i->framePointer = object_to_smallint(i->stack->elements[framePointer - 1]);
52   i->codePointer = object_to_smallint(i->stack->elements[framePointer - 4]);
53   i->lexicalContext = (struct LexicalContext*) i->stack->elements[i->framePointer - 2];
54   i->closure = (struct Closure*) i->stack->elements[i->framePointer - 3];
55   i->method = i->closure->method;
56   i->codeSize = array_size(i->method->code);
60 Compiler
61 --------
63 A simple example:
65 ~~~
67 [ | :c genCode|
68 genCode: (c generate:
70  1 + 1
71
72 method sourceTree result: Nil &topLevel: True) code.
73 c decompile: genCode
74 ] applyWith: VM SSACompiler new.
76 ~~~
78 Inside a function definition:
80 ~~~
82 [ | :c genCode|
83 genCode: (c generate:
85  block@(Method traits) on: c@(Condition traits) do: handler
86 [| context |
87   context: (c cloneSettingSlots: #(handlers exitContinuation)
88               to: {{handler}. [| :result | ^ result]}).
89   conditionStack push: context.
90   block ensure: [conditionStack pop]
93
94 method sourceTree result: Nil &topLevel: True) code.
95 c decompile: genCode third code
96 ] applyWith: VM SSACompiler new.
98 ~~~
100 Inside the closure:
104 [ | :c genCode|
105 genCode: (c generate:
107  block@(Method traits) on: c@(Condition traits) do: handler
108 [| context |
109   context: (c cloneSettingSlots: #(handlers exitContinuation)
110               to: {{handler}. [| :result | ^ result]}).
111   conditionStack push: context.
112   block ensure: [conditionStack pop]
116 method sourceTree result: Nil &topLevel: True) code.
117 c decompile: (genCode third code at: 13) code
118 ] applyWith: VM SSACompiler new.
122 See what is getting called:
126 VM SSACompiler new decompile: (#handle: findOn: {mainWindow. PaintEvent newContext: mainWindow context}) method code.