aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-09-15 15:07:19 +0200
committerDrahflow <drahflow@gmx.de>2013-09-15 15:07:19 +0200
commitec6490466eae96b4d8410333ae63f7c057e2d224 (patch)
tree4009f6d31fd564fbbd1035c284402fa97643faba /compiler
parent7af5d9f1f7c7746fb10b8e26eda693625f871883 (diff)
References now stored separately from opcodes
Diffstat (limited to 'compiler')
-rw-r--r--compiler/elymasAsm.ey5
-rw-r--r--compiler/elymasAsmLib.ey84
-rw-r--r--compiler/elymasGlobal.ey331
-rw-r--r--compiler/elymasGlobalSysAsm.ey8
4 files changed, 245 insertions, 183 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index a54fbe1..e1f7d5a 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -1167,7 +1167,10 @@
}' each
STACKSIZE sys .asm .alloc _ globalAllocations .register
- .base ==quoteEncodingBuffer
+ .base ==quoteEncodingBufferCode
+
+ STACKSIZE sys .asm .alloc _ globalAllocations .register
+ .base ==quoteEncodingBufferObjects
{ ==opcodes
opcodes len 1 sub PAGESIZE div 1 add PAGESIZE mul sys .asm .alloc /codearea defv
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index b8cf32c..280a351 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -101,20 +101,25 @@
[ :globalAllocations .base :imm64 ] ==globalAllocationList # FIXME what is this for? directly use :globalAllocations
> { defv }' allocateOffsetStruct
- { _ =*array len _ 4 div ==largeMoves
- 4 mod ==smallMoves
- 0 ==i
- largeMoves {
- i _ 4 add =i
- _ [ 3 2 1 0 ] add array { -01 256 mul add } fold -01 /rdi :movlImmMemDisp8
- } rep
- i /rdi :addqImm8Reg
- smallMoves {
- i _ 1 add =i
- array /rdi :movbImmMem
- /rdi :incqReg
- } rep
- } /loadToRdi deff
+ { ==register
+ { _ =*array len _ 4 div ==largeMoves
+ 4 mod ==smallMoves
+ 0 ==i
+ largeMoves {
+ i _ 4 add =i
+ _ [ 3 2 1 0 ] add array { -01 256 mul add } fold -01 register :movlImmMemDisp8
+ } rep
+ i register :addqImm8Reg
+ smallMoves {
+ i _ 1 add =i
+ array register :movbImmMem
+ register :incqReg
+ } rep
+ }
+ } /loadToXXX deff
+
+ /rdi loadToXXX /loadToRdi deff
+ /rbp loadToXXX /loadToRbp deff
# internal functions, ABI follows SysV standards
@@ -422,16 +427,15 @@
/loopThroughCallStack :jbLbl8
# start from encoding buffer and mark all reachable blocks
- # TODO clear encoding buffer in the allocating functions (or mark via :ud2 at beginning)
- :quoteEncodingBuffer /rsi :movqImmReg
- [ 0 1 ] { [ :ud2 ] * } each 256 mul add /rsi :cmpwImmMem
+ :quoteEncodingBufferObjects /rsi :movqImmReg
+ 0 /rsi :cmpqImm8Mem
/quoteEncodingBufferUnused :jzLbl8
:STACKSIZE 8 sub /rcx :movqImmReg
@loopThroughEncodingBuffer
/rsi /rdi :movqMemReg
/markObject :callqLbl32
- /rsi :incqReg
+ 8 /rsi :addqImm8Reg
/loopThroughEncodingBuffer :loopLbl8
@quoteEncodingBufferUnused
@@ -608,20 +612,22 @@
/rcx :pushqReg
/rdi /ecx :movlMemReg
- 8 /rdi :addqImm8Reg
+ 8 /rdi /rcx :subqMemDisp8Reg
+ 8 /rdi /rdi :addqMemDisp8Reg
16 /rcx :subqImm8Reg
+ /markFunctionCodeDone :jzLbl8
+ 16 /rdi :addqImm8Reg
+ 3 /rcx :shrqImm8Reg
@markFunctionCodeLoop
- /rdi /r11 :cmpqMemReg
- /codePartNotObject :jbeLbl32 # pointing above the heap
/rdi :pushqReg
/rdi /rdi :movqMemReg
/markObject :callqLbl32
/rdi :popqReg
-
- @codePartNotObject
- /rdi :incqReg
+ 8 /rdi :addqImm8Reg
/markFunctionCodeLoop :loopLbl8
+
+ @markFunctionCodeDone
/rcx :popqReg
:retn
@@ -975,7 +981,7 @@
# rdi -> number of code bytes
# rax <- address of code block on heap
[
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
internalAllocate /rax :movqImmReg
/rax :callqReg
@@ -1056,29 +1062,45 @@
:retn
] /unscopingFunctionFooter defv
+ # rdi -> end of allocated code (address after last used opcode in quoteEncodingBufferCode)
+ # rbp -> end of allocated object pointers (address after last used address in quoteEncodingBufferObjects)
+ # rax <- resulting code object
{
- :quoteEncodingBuffer /rax :movqImmReg
+ :quoteEncodingBufferCode /rax :movqImmReg
/rax /rdi :subqRegReg
- /rdi :pushqReg # store opcode byte count
+
+ :quoteEncodingBufferObjects /rax :movqImmReg
+ /rax /rbp :subqRegReg
/rdi :decqReg
3 /rdi :shrqImm8Reg
/rdi :incqReg
3 /rdi :shlqImm8Reg
+
+ /rbp :pushqReg # store pointer byte count
+ /rdi :pushqReg # store opcode byte count (rounded up to 8 byte)
+
+ /rbp /rdi :addqRegReg
internalAllocateCode /rax :movqImmReg
/rax :callqReg
# rax == code block on heap
# copy opcodes
- :quoteEncodingBuffer /rsi :movqImmReg
- 8 /rax /rdi :leaqMemDisp8Reg
+ :quoteEncodingBufferCode /rsi :movqImmReg
+ 16 /rax /rdi :leaqMemDisp8Reg
+ /rcx :popqReg
+ /rcx 8 /rax :movqRegMemDisp8
+ :reprcx :movsb
+
+ # copy object pointers
+ :quoteEncodingBufferObjects /rsi :movqImmReg
/rcx :popqReg
:reprcx :movsb
# mark buffer unused
- :quoteEncodingBuffer /rdi :movqImmReg
- [ 0 1 ] { [ :ud2 ] * } each 256 mul add /rdi :movwImmMem
+ :quoteEncodingBufferObjects /rdi :movqImmReg
+ /rcx /rdi :movqRegMem # rcx is conveniently zero
} /allocateCodeFromEncodingBuffer deff
{ strToUTF8Bytes _ =*v len _ ==exactLength
diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey
index 4c42a0b..2918a19 100644
--- a/compiler/elymasGlobal.ey
+++ b/compiler/elymasGlobal.ey
@@ -364,7 +364,7 @@
@untyped
24 /rdx /rax :movqMemDisp8Reg
- 8 /rax :addqImm8Reg
+ 16 /rax :addqImm8Reg
/rax :callqReg
/r15 /rcx :movqMemReg
@@ -382,7 +382,7 @@
/typedUnscoped :jnzLbl8
24 /rdx /rax :movqMemDisp8Reg
- 8 /rax :addqImm8Reg
+ 16 /rax :addqImm8Reg
/rax :callqReg
/r15 :pushqMem
@@ -461,7 +461,7 @@
/typedCommonCheck :loopLbl8
24 /rdx /rax :movqMemDisp8Reg
- 8 /rax :addqImm8Reg
+ 16 /rax :addqImm8Reg
/rax :callqReg
/r15 /rcx :movqMemReg
@@ -982,7 +982,7 @@
/rcx /r15 :movqRegMem
/rsi /rax :movqRegMem
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
/rdi :callqReg
/r15 /rcx :movqMemReg
@@ -1138,7 +1138,9 @@
@patchConstantActiveGeneral
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 8 /rdi /rbp :movqMemDisp8Reg
+ 16 1 /rbp /rdi /rbp :leaqMemIndexScaleDisp8Reg
+ 16 /rdi :addqImm8Reg
[
/rbx :popqReg
@@ -1153,8 +1155,10 @@
/rax :jmpqReg
] ::loadToRdi
+ /rdx 0 /rbp :movqRegMemDisp8 # save reference for the GC
+
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1174,11 +1178,14 @@
@patchConstantNormalFunctionScopedUntyped
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 8 /rdi /rbp :movqMemDisp8Reg
+ 16 1 /rbp /rdi /rbp :leaqMemIndexScaleDisp8Reg
+ 16 /rdi :addqImm8Reg
8 /rdx /rcx :movqMemDisp8Reg # load function scope
- 24 /rdx /rdx :movqMemDisp8Reg # load actual function code
+ 24 /rdx /rbx :movqMemDisp8Reg # load actual function code
+ 16 /rbx :addqImm8Reg
[
/rsi :movqImmOOBReg
@@ -1186,17 +1193,32 @@
/rcx /rdi :movqRegMem
8 /rdi :addqImm8Reg
[
+ 16 /r15 :subqImm8Reg
+ 8 /r15 :popqMemDisp8
+
+ ::currentScope /rax :movqImmReg
+ /rsi /rax :xchgqRegMem
+ /rsi /r15 :movqRegMem
/rdi :movqImmOOBReg
] ::loadToRdi
- /rdx /rdi :movqRegMem
+ /rbx /rdi :movqRegMem
8 /rdi :addqImm8Reg
[
- internalConstantNormalFunctionScopedUntypedJumpPad /rax :movqImmReg
- /rax :jmpqReg
+ /rdi :callqReg
+
+ /r15 /rsi :movqMemReg
+ ::currentScope /rax :movqImmReg
+ /rsi /rax :movqRegMem
+
+ 8 /r15 :pushqMemDisp8
+ 16 /r15 :addqImm8Reg
+ :retn
] ::loadToRdi
+ /rdx 0 /rbp :movqRegMemDisp8 # save object reference
+
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1211,26 +1233,25 @@
@patchConstantNormalFunctionUnscopedUntyped
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 8 /rdi /rbp :movqMemDisp8Reg
+ 16 1 /rbp /rdi /rbp :leaqMemIndexScaleDisp8Reg
+ 16 /rdi :addqImm8Reg
24 /rdx /rdx :movqMemDisp8Reg # load actual function code
- 8 /rdx :addqImm8Reg
+ 16 /rdx /rcx :leaqMemDisp8Reg # correct for header
[
/rax :movqImmOOBReg
] ::loadToRdi
- /rdx /rdi :movqRegMem
+ /rcx /rdi :movqRegMem
8 /rdi :addqImm8Reg
[
/rax :jmpqReg
- /rax :movqImmOOBReg
] ::loadToRdi
- 8 /rdx :subqImm8Reg
- /rdx /rdi :movqRegMem # save the address for the GC
- 8 /rdi :addqImm8Reg
+ /rdx 0 /rbp :movqRegMemDisp8 # save the address for the GC
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1239,7 +1260,8 @@
@patchConstantPassive
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ # TODO: could reset string reference here
+ 16 /rdi :addqImm8Reg
[
/rbx :popqReg
@@ -1253,7 +1275,7 @@
] ::loadToRdi
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1288,9 +1310,9 @@
:ud2
@patchStaticPassiveParentCountWithinLimits
-
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ # TODO: could reset string reference here
+ 16 /rdi :addqImm8Reg
[
::currentScope /rax :movqImmReg
@@ -1320,7 +1342,7 @@
/esi /rdi :movlRegMem # patch offset
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1342,7 +1364,7 @@
/esi /rdi :movlRegMem # patch offset
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1360,9 +1382,9 @@
:ud2
@patchStaticActiveParentCountWithinLimits
-
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ # TODO: could reset string reference here
+ 16 /rdi :addqImm8Reg
[
::currentScope /rax :movqImmReg
@@ -1394,7 +1416,7 @@
/esi /rdi :movlRegMem # patch offset
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1418,7 +1440,7 @@
/esi /rdi :movlRegMem # patch offset
8 /r15 /rdi :movqMemDisp8Reg
- 8 /rdi :addqImm8Reg
+ 16 /rdi :addqImm8Reg
16 /r15 :addqImm8Reg
/r15 :pushqMem
@@ -1432,107 +1454,108 @@
[[
/rbx :popqReg
/rsi :popqReg
- 8 /rsi :addqImm8Reg # move to start of code
- /rsi :pushqReg
- :quoteEncodingBuffer /rdi :movqImmReg
-
- %34 /rcx :movqImmReg # skip to generated code
- :reprcx :movsb
-
- @parseLoop
- 0 [ 0 :callqRel32 ] * 0 /rsi :cmpbImmMemDisp8
- /parseFooter :jzLbl32
- 1 [ 8 /rax :addqImm8Reg ] * 11 /rsi :cmpbImmMemDisp8
- /parseFunctionCall :jzLbl32
- 0 [ /rax :pushqReg ] * 10 /rsi :cmpbImmMemDisp8
- /parseConstantPush :jzLbl32
- 0 [ /rax :callqReg ] * 10 /rsi :cmpbImmMemDisp8
- /parseConstantCall :jzLbl32
-
- "unknown assembly instruction during internalOptimizeGeneratedScopedFunction" ::outputError
- :ud2
-
- @parseFunctionCall
- 2 /rsi /rdx :movqMemDisp8Reg # load function address
- 1 [ 0 /rax :movqImmReg ] * 9 /rdx :cmpbImmMemDisp8
- /parseFunctionCallSkip :jnzLbl32
- 0 [ /rax :jmpqReg ] * 18 /rdx :cmpbImmMemDisp8
- /parseFunctionCallSkip :jnzLbl32
- 1 [ /rax :jmpqReg ] * 19 /rdx :cmpbImmMemDisp8
- /parseFunctionCallSkip :jnzLbl32
-
- 10 /rdx /rcx :movqMemDisp8Reg # load final function address
- /rax :movqImmOOBReg ::HEAPEND
- /rax /rcx :cmpqRegReg
- /parseFunctionUnGCable :jaeLbl8
-
- # @parseFunctionGCable
- [
- /rax :movqImmOOBReg
- ] ::loadToRdi
- 8 /rcx :subqImm8Reg # make address point to code block object
- /rcx /rdi :movqRegMem # load final function address
- 8 /rdi :addqImm8Reg
- [
- 8 /rax :addqImm8Reg # skip code block object header
- /rax :callqReg
- ] ::loadToRdi
- /parseFunctionCallDone :jmpLbl8
-
- @parseFunctionUnGCable
- [
- /rax :movqImmOOBReg
- ] ::loadToRdi
- /rcx /rdi :movqRegMem # load final function address
- 8 /rdi :addqImm8Reg
- [
- /rax :callqReg
- ] ::loadToRdi
-
- @parseFunctionCallDone
- 16 /rsi :addqImm8Reg
- /parseLoop :jmpLbl32
-
- @parseFunctionCallSkip
- :movsq # verbatim copy
- :movsq
- /parseLoop :jmpLbl32
-
- @parseConstantPush
- :movsq # verbatim copy
- :movsw
- :movsb
- /parseLoop :jmpLbl32
-
- @parseConstantCall
- :movsq # verbatim copy
- :movsl
- /parseLoop :jmpLbl32
-
- @parseFooter
- ::scopingFunctionFooter ::loadToRdi
- ::allocateCodeFromEncodingBuffer
- # rax == optimized code object on heap
-
- # patch indirection to new code into old
- /rsi :popqReg # rsi == old code start
- /rsi /rdi :movqRegReg
- [
- /rax :movqImmOOBReg
- ] ::loadToRdi
- 8 /rax :addqImm8Reg
- /rax /rdi :movqRegMem
- 8 /rax :subqImm8Reg
- 8 /rdi :addqImm8Reg
- [
- /rax :jmpqReg
- /rax :movqImmOOBReg
- ] ::loadToRdi
- /rax /rdi :movqRegMem
-
- # TODO kill remaining opcodes to remove GC-followable memory addresses
- # possible solution: updatable exact-length field for code blocks
- # but think of the return stack
+# FIXME FIXME FIXME this should be reenabled soonish
+# 8 /rsi :addqImm8Reg # move to start of code
+# /rsi :pushqReg
+# :quoteEncodingBuffer /rdi :movqImmReg
+#
+# %34 /rcx :movqImmReg # skip to generated code
+# :reprcx :movsb
+#
+# @parseLoop
+# 0 [ 0 :callqRel32 ] * 0 /rsi :cmpbImmMemDisp8
+# /parseFooter :jzLbl32
+# 1 [ 8 /rax :addqImm8Reg ] * 11 /rsi :cmpbImmMemDisp8
+# /parseFunctionCall :jzLbl32
+# 0 [ /rax :pushqReg ] * 10 /rsi :cmpbImmMemDisp8
+# /parseConstantPush :jzLbl32
+# 0 [ /rax :callqReg ] * 10 /rsi :cmpbImmMemDisp8
+# /parseConstantCall :jzLbl32
+#
+# "unknown assembly instruction during internalOptimizeGeneratedScopedFunction" ::outputError
+# :ud2
+#
+# @parseFunctionCall
+# 2 /rsi /rdx :movqMemDisp8Reg # load function address
+# 1 [ 0 /rax :movqImmReg ] * 9 /rdx :cmpbImmMemDisp8
+# /parseFunctionCallSkip :jnzLbl32
+# 0 [ /rax :jmpqReg ] * 18 /rdx :cmpbImmMemDisp8
+# /parseFunctionCallSkip :jnzLbl32
+# 1 [ /rax :jmpqReg ] * 19 /rdx :cmpbImmMemDisp8
+# /parseFunctionCallSkip :jnzLbl32
+#
+# 10 /rdx /rcx :movqMemDisp8Reg # load final function address
+# /rax :movqImmOOBReg ::HEAPEND
+# /rax /rcx :cmpqRegReg
+# /parseFunctionUnGCable :jaeLbl8
+#
+# # @parseFunctionGCable
+# [
+# /rax :movqImmOOBReg
+# ] ::loadToRdi
+# 8 /rcx :subqImm8Reg # make address point to code block object
+# /rcx /rdi :movqRegMem # load final function address
+# 8 /rdi :addqImm8Reg
+# [
+# 8 /rax :addqImm8Reg # skip code block object header
+# /rax :callqReg
+# ] ::loadToRdi
+# /parseFunctionCallDone :jmpLbl8
+#
+# @parseFunctionUnGCable
+# [
+# /rax :movqImmOOBReg
+# ] ::loadToRdi
+# /rcx /rdi :movqRegMem # load final function address
+# 8 /rdi :addqImm8Reg
+# [
+# /rax :callqReg
+# ] ::loadToRdi
+#
+# @parseFunctionCallDone
+# 16 /rsi :addqImm8Reg
+# /parseLoop :jmpLbl32
+#
+# @parseFunctionCallSkip
+# :movsq # verbatim copy
+# :movsq
+# /parseLoop :jmpLbl32
+#
+# @parseConstantPush
+# :movsq # verbatim copy
+# :movsw
+# :movsb
+# /parseLoop :jmpLbl32
+#
+# @parseConstantCall
+# :movsq # verbatim copy
+# :movsl
+# /parseLoop :jmpLbl32
+#
+# @parseFooter
+# ::scopingFunctionFooter ::loadToRdi
+# ::allocateCodeFromEncodingBuffer
+# # rax == optimized code object on heap
+#
+# # patch indirection to new code into old
+# /rsi :popqReg # rsi == old code start
+# /rsi /rdi :movqRegReg
+# [
+# /rax :movqImmOOBReg
+# ] ::loadToRdi
+# 8 /rax :addqImm8Reg
+# /rax /rdi :movqRegMem
+# 8 /rax :subqImm8Reg
+# 8 /rdi :addqImm8Reg
+# [
+# /rax :jmpqReg
+# /rax :movqImmOOBReg
+# ] ::loadToRdi
+# /rax /rdi :movqRegMem
+#
+# # TODO kill remaining opcodes to remove GC-followable memory addresses
+# # possible solution: updatable exact-length field for code blocks
+# # but think of the return stack
/rbx :jmpqReg
]] /internalOptimizeGeneratedScopedFunction defv
@@ -1636,23 +1659,24 @@
@constructQuotedResolve
# construct non-capturing function
- :quoteEncodingBuffer /rdi :movqImmReg
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
::unscopingFunctionHeader ::loadToRdi
# push identifier
- [ /rax :movqImmOOBReg ] _ len 2 eq assert
- 2 dearray 256 mul add
- /rdi :movwImmMem
+ [ /rax :movqImmOOBReg ] ::loadToRdi
/r15 /rsi :movqMemReg
- /rsi 2 /rdi :movqRegMemDisp8
- 10 /rdi :addqImm8Reg
+ /rsi /rdi :movqRegMem
+ /rsi 0 /rbp :movqRegMemDisp8
+ 8 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
/rax :pushqReg
0 :callqRel32
/rax :popqReg
# 16 bytes code here, header length, and code block header
- 16 ::unscopingFunctionHeader len add 8 add /rax :subqImm8Reg
+ 16 ::unscopingFunctionHeader len add 16 add /rax :subqImm8Reg
/rax :pushqReg
64 { :nop } rep # FIXME the maximum patch length still needs to be determined
internalExecuteIdentifierUnquotedAndPatchLateResolve /rax :movqImmReg
@@ -1721,7 +1745,8 @@
/r15 :popqMem
# construct non-capturing function
- :quoteEncodingBuffer /rdi :movqImmReg
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
::unscopingFunctionHeader ::loadToRdi
/rcx :popqReg
@@ -1732,7 +1757,9 @@
2 dearray 256 mul add
/rdi :movwImmMem
/rdx 2 /rdi :movqRegMemDisp8
+ /rdx 0 /rbp :movqRegMemDisp8
10 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
/rax :pushqReg
|ey* /rax :movqImmReg
@@ -1741,7 +1768,9 @@
] ::loadToRdi
# push function g
/rcx /rdi :movqRegMem
+ /rcx 0 /rbp :movqRegMemDisp8
8 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
/rax :pushqReg
|ey* /rax :movqImmReg
@@ -2228,7 +2257,8 @@
/rdx :pushqReg # store address of begin marker
- :quoteEncodingBuffer /rdi :movqImmReg
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
header ::loadToRdi
@search
@@ -2255,10 +2285,12 @@
2 dearray 256 mul add
/rdi :movwImmMem
/rsi 2 /rdi :movqRegMemDisp8
+ /rsi 0 /rbp :movqRegMemDisp8
[ /rax :pushqReg ] _ len 1 eq assert
1 dearray
10 /rdi :movbImmMemDisp8
11 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
/search :jmpLbl32
@functionFound
@@ -2275,10 +2307,12 @@
[ /rax :movqImmOOBReg ] _ len 2 eq assert
2 dearray 256 mul add
/rdi :movwImmMem
+ /rax 0 /rbp :movqRegMemDisp8 # save code object pointer
+ 16 /rax :addqImm8Reg # but add code offset, before encoding call
/rax 2 /rdi :movqRegMemDisp8
10 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
- 8 /rax :addqImm8Reg # add code offset only here, to keep the address available for GC
/rax :callqReg
] ::loadToRdi
/search :jmpLbl32
@@ -2288,10 +2322,12 @@
2 dearray 256 mul add
/rdi :movwImmMem
/rsi 2 /rdi :movqRegMemDisp8
+ /rsi 0 /rbp :movqRegMemDisp8
[ /rax :pushqReg ] _ len 1 eq assert
1 dearray
10 /rdi :movbImmMemDisp8
11 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
|ey* /rax :movqImmReg
/rax :callqReg
@@ -2310,7 +2346,7 @@
/rax :popqReg
/rbx :movqImmOOBReg
] ::loadToRdi
- :quoteEncodingBuffer /rbx :movqImmReg
+ :quoteEncodingBufferCode /rbx :movqImmReg
/rdi /rax :movqRegReg
5 /rax :addqImm8Reg
/rbx /rax :subqRegReg
@@ -2363,7 +2399,8 @@
# create function which
# returns a function with the current scope captured
- :quoteEncodingBuffer /rdi :movqImmReg
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
::unscopingFunctionHeader ::loadToRdi
# 1. load inner code block
@@ -2371,7 +2408,9 @@
2 dearray 256 mul add
/rdi :movwImmMem
/rax 2 /rdi :movqRegMemDisp8
+ /rax 0 /rbp :movqRegMemDisp8
10 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
[
::currentScope /rax :movqImmReg
@@ -2662,7 +2701,7 @@
{ =*resolve ==createScopeEntry
{ ==name
# create function
- name resolve 8 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
+ name resolve 16 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
/rsi /rsi :xorqRegReg # library functions don't have a captured scope
# TODO: put a type here where applicable
/rdx /rdx :xorqRegReg
@@ -2683,7 +2722,7 @@
{ =*resolve ==typeToUse ==createScopeEntry
{ ==name
# create function
- name resolve 8 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
+ name resolve 16 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
/rsi /rsi :xorqRegReg # library functions don't have a captured scope
typeToUse /rdx :movqImmReg
@@ -2703,7 +2742,7 @@
{
[ /eydefv /eydeff /eydefq ] { ==name
# create function
- name | 8 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
+ name | 16 sub /rdi :movqImmReg # adjust for expected (but non-existent) code block header size
::currentScope /rsi :movqImmReg
/rsi /rsi :movqMemReg
/rdx /rdx :xorqRegReg # untyped
diff --git a/compiler/elymasGlobalSysAsm.ey b/compiler/elymasGlobalSysAsm.ey
index e9c1ad5..0c54b05 100644
--- a/compiler/elymasGlobalSysAsm.ey
+++ b/compiler/elymasGlobalSysAsm.ey
@@ -225,7 +225,7 @@
/rdx :popqReg
24 /rdx /rdx :movqMemDisp8Reg
- 8 /rdx :addqImm8Reg
+ 16 /rdx :addqImm8Reg
/rdx 8 /rax :movqRegMemDisp8
/rax :pushqReg
@@ -251,11 +251,9 @@
/rbx /rax :movqRegMem # 112
# empty encoding buffer to ensure the GC does not follow residue from freeze into unallocated memory
- :quoteEncodingBuffer /rdi :movqImmReg
- :STACKSIZE 8 sub /rcx :movqImmReg
- 3 /rcx :shrqImm8Reg
+ :quoteEncodingBufferObjects /rdi :movqImmReg
/rax /rax :xorqRegReg
- :reprcx :stosq
+ /rax /rdi :movqRegMem
|ey* /rax :movqImmReg
/rax :callqReg