Modifications

This commit is contained in:
2026-09-07 11:44:42 +00:00
parent 617dbeb988
commit 457e63ad8e
7 changed files with 259 additions and 225 deletions
+50 -13
View File
@@ -36,23 +36,50 @@ which in the example is:
REPLACE it with:
[6] = Fclosure8 Const(1) [],
[8] = Fclosure8 Const(0) [],
[18] = GetField Atom(atom("prototype")) [6],
[8] = Fclosure8 Const(0) [],
[] = PutField Atom(file_atom[5]) [8, 18],
[] = Nop None [],
[] = Nop None [],
[] = Nop None [],
[] = Nop None [],
INSTRUCTION BY INSTRUCTION:
PushConst8 Const(1) + DefineClass [5,4] -> Fclosure8 Const(1), keep dst [6]
Fclosure8 Const(0) -> unchanged (the method closure)
DefineMethod atom=A [8,7] -> GetField "prototype" [6]
then PutField atom=A [8,18]
Fclosure8 Const(2) -> deleted
SetHomeObject -> deleted
PutLoc1 [12] -> deleted
Drop [11] -> deleted
PushConst8 Const(1) ; DefineClass [5,4]
-> Fclosure8 Const(1), which keeps the DefineClass dst [6].
[18] is any fresh value id.
Repeat the DefineMethod line for each method in the class.
GetField "prototype" [6]
-> emitted once for the whole class, into a fresh value id [18].
It is NOT emitted per method: the prototype cannot change
between the PutFields below. A class with no methods does not
emit it at all.
Fclosure8 Const(0)
-> unchanged. It is the method closure.
DefineMethod atom=A [8,7]
-> PutField atom=A [8, 18], reading the [18] from above.
Repeat the Fclosure8/PutField pair for each method.
Fclosure8 Const(2) ; SetHomeObject ; PutLoc1 [12] ; Drop [11]
-> deleted. This is the field-initialiser tail.
Nop
-> padding, described below.
LENGTH, and why the rewrite is written in place:
matched = 2 + 2n instructions, plus 4 more if the field-initialiser
tail is there (n = the number of methods).
emitted = 2 + 2n instructions, or 1 when n is 0.
So the emission is never longer than what it replaces. It is written
straight over the matched range and the slack is padded with Nop,
which pops and pushes nothing. Every instruction outside a class
build keeps its position, so no other range has to be adjusted.
In the example: 8 matched, 4 emitted, 4 Nop.
REMEMBER for step 2 and 3:
@@ -200,7 +227,17 @@ NOT TOUCHED (passed through unchanged)
====================================================================
LEFT BEHIND (removed by a later pass)
LEFT BEHIND (an empty function)
====================================================================
FnById(4), the fields function. Nothing references it anymore.
FnById(4), the fields function. Step 1 deleted the fclosure8 that
built it, and step 2 moved its writes into the constructor, so
nothing references it anymore.
Step 2 empties it:
code: [],
It is NOT removed from the function list. A function id is an index
into that list, so removing one would renumber every function after
it and break every FnById that points past it.