aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-09-22 11:26:45 +0200
committerDrahflow <drahflow@gmx.de>2013-09-22 11:26:45 +0200
commit65b530782c309fa7bd9b3781f23a0ce0a3b29a3b (patch)
tree7af0f9e9d7a9828582f6bebf0732c396f855dd6a
parenteea02bbc59f4f0ece2756cdc846d351238d2b6a7 (diff)
=abc and |abc now optimized to static access
-rw-r--r--compiler/elymasAsm.ey40
-rw-r--r--compiler/elymasAsmLib.ey4
-rw-r--r--compiler/elymasGlobal.ey69
-rw-r--r--compiler/elymasGlobalSys.ey57
-rw-r--r--compiler/elymasGlobalSysOpt.ey2
-rw-r--r--compiler/standardClient.ey2
-rw-r--r--elymas/lib/sys/opt.ey404
-rw-r--r--elymas/optimized.ey2
8 files changed, 399 insertions, 181 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index ca3bdd7..fcb584a 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -73,19 +73,39 @@
} /modrm00 deff
{ ==mem ==reg
- mem [ /spl /sp /esp /rsp ] streq any not assert
-
- %40
- mem regno %07 band add
- reg regno 8 mul %38 band add
+ mem [ /spl /sp /esp /rsp ] streq any {
+ # actually encode sib with rsp index register (to get it ignored)
+ %40
+ /sib regno %07 band add
+ reg regno 8 mul %38 band add
+
+ # sib-byte
+ %00 # index = 1 (ignored anyway)
+ %38 /rsp regno 8 mul band add # (ignored)
+ %07 mem regno band add
+ } {
+ %40
+ mem regno %07 band add
+ reg regno 8 mul %38 band add
+ } ? *
} /modrm01 deff
{ ==mem ==reg
- mem [ /spl /sp /esp /rsp ] streq any not assert
-
- %80
- mem regno %07 band add
- reg regno 8 mul %38 band add
+ mem [ /spl /sp /esp /rsp ] streq any {
+ # actually encode sib with rsp index register (to get it ignored)
+ %80
+ /sib regno %07 band add
+ reg regno 8 mul %38 band add
+
+ # sib-byte
+ %00 # index = 1 (ignored anyway)
+ %38 /rsp regno 8 mul band add # (ignored)
+ %07 mem regno band add
+ } {
+ %80
+ mem regno %07 band add
+ reg regno 8 mul %38 band add
+ } ? *
} /modrm10 deff
{ ==mem ==reg
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index e54c5c0..0cb2c6e 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -81,8 +81,8 @@
{ %00 %00 %00 %00 %00 %60 %00 %00 } /HEAPBASE deff
{ %00 %00 %00 %00 %00 %50 %00 %00 } /BLOCKBASE deff
{ %00 %00 %00 %00 %00 %40 %00 %00 } /MARKBASE deff
- # 4096 16 mul 8 mul ==ALLOCCHUNKSIZE # minimum ALLOCCHUNKSIZE
- 4096 16 mul 8 mul 256 mul ==ALLOCCHUNKSIZE # FIXME: there is still some wonkyness with freezing
+ 4096 16 mul 8 mul ==ALLOCCHUNKSIZE # minimum ALLOCCHUNKSIZE
+ # 4096 16 mul 8 mul 256 mul ==ALLOCCHUNKSIZE # FIXME: there is still some wonkyness with freezing
<
# current end of heap memory (grows upwards)
diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey
index eb5fe8b..1820725 100644
--- a/compiler/elymasGlobal.ey
+++ b/compiler/elymasGlobal.ey
@@ -1459,6 +1459,9 @@
58 /rax :btsqImm8Mem
/alreadyOptimized :jcLbl8
/rax :pushqReg
+
+ ::currentScope /rcx :movqImmReg
+ /rcx :pushqMem
/rax :pushqReg
/rax :movqImmOOBReg "sys" ::string
@@ -1477,6 +1480,7 @@
/rax :callqReg
/rcx :popqReg # result object (not necessarily new code object though)
+ /rax :popqReg # pop returned scope object
/rax :popqReg # old object
/rax /rcx :cmpqRegReg
@@ -2312,28 +2316,55 @@
# rax == (inner) code object on heap
# create function which
- # returns a function with the current scope captured
- :quoteEncodingBufferCode /rdi :movqImmReg
- :quoteEncodingBufferObjects /rbp :movqImmReg
- ::unscopingFunctionHeader ::loadToRdi
-
- # 1. load inner code block
- [ /rdi :movqImmOOBReg ] _ len 2 eq assert
- 2 dearray 256 mul add
- /rdi :movwImmMem
- /rax 2 /rdi :movqRegMemDisp8
- /rax 0 /rbp :movqRegMemDisp8
- 10 /rdi :addqImm8Reg
- 8 /rbp :addqImm8Reg
-
- [
- ::currentScope /rax :movqImmReg
- /rax /rsi :movqMemReg
+ capturing {
+ # returns a function with the current scope captured
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
+ ::unscopingFunctionHeader ::loadToRdi
+
+ # load inner code block
+ [ /rdi :movqImmOOBReg ] _ len 2 eq assert
+ 2 dearray 256 mul add
+ /rdi :movwImmMem
+ /rax 2 /rdi :movqRegMemDisp8
+ /rax 0 /rbp :movqRegMemDisp8
+ 10 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
+
+ [
+ ::currentScope /rax :movqImmReg
+ /rax /rsi :movqMemReg
+ /rdx /rdx :xorqRegReg
+ ::internalAllocateFunction /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg
+ ] ::unscopingFunctionFooter cat ::loadToRdi
+ } {
+ # create constant function from inner code block
+ /rax /rdi :movqRegReg
+ /rsi /rsi :xorqRegReg # non-capturing
/rdx /rdx :xorqRegReg
::internalAllocateFunction /rax :movqImmReg
/rax :callqReg
- /rax :pushqReg
- ] ::unscopingFunctionFooter cat ::loadToRdi
+
+ :quoteEncodingBufferCode /rdi :movqImmReg
+ :quoteEncodingBufferObjects /rbp :movqImmReg
+ ::unscopingFunctionHeader ::loadToRdi
+
+ # rax == function object
+
+ [ /rax :movqImmOOBReg ] _ len 2 eq assert
+ 2 dearray 256 mul add
+ /rdi :movwImmMem
+ /rax 2 /rdi :movqRegMemDisp8
+ /rax 0 /rbp :movqRegMemDisp8
+ 10 /rdi :addqImm8Reg
+ 8 /rbp :addqImm8Reg
+
+ [
+ /rax :pushqReg
+ ] ::unscopingFunctionFooter cat ::loadToRdi
+ } ? *
::internalAllocateCodeFromEncodingBuffer /rax :movqImmReg
/rax :callqReg
diff --git a/compiler/elymasGlobalSys.ey b/compiler/elymasGlobalSys.ey
index 3a1c988..55f2369 100644
--- a/compiler/elymasGlobalSys.ey
+++ b/compiler/elymasGlobalSys.ey
@@ -2,7 +2,7 @@
"sys" enterSubScope
<
- # handle an identifier in the current scope according to current quote level
+ # handle an identifier in a given scope according to current quote level
# 0 -> scope to execute identifier in
# 1 -> identifier to handle
# 0 <- scope after execution
@@ -29,6 +29,61 @@
8 /r15 :addqImm8Reg
:retn
]] /eyexecuteIdentifier defv
+
+ # resolve an identifier in a given scope and return full resolve information
+ # 0 -> scope to resolve identifier in
+ # 1 -> identifier to resolve
+ # 0 <- address of resolved object (0 if nonexistent)
+ # 1 <- activation mode and constness of element (only present if resolution successful)
+ # 2 <- memory address of entry (only present if resolution successful)
+ # 3 <- number of parent pointers followed (only present if resolution successful)
+ # 4 <- entry index * 8 within scope (only present if resolution successful)
+ # 5 <- 0 if within scope data area, 1 if within extension area (only present if resolution successful)
+ [[
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ /rdi :popqReg
+ /rsi :popqReg
+
+ ::internalResolve /rax :movqImmReg
+ /rax :callqReg
+
+ /rax /rax :andqRegReg
+ /failure :jzLbl32
+
+ 48 /r15 :subqImm8Reg
+ /rbp 40 /r15 :movqRegMemDisp8
+ /rsi 32 /r15 :movqRegMemDisp8
+ /rdi 24 /r15 :movqRegMemDisp8
+ /rcx 16 /r15 :movqRegMemDisp8
+ /rdx 8 /r15 :movqRegMemDisp8
+ /rax /r15 :movqRegMem
+
+ [ 40 32 24 16 8 0 ] { ==o
+ ::internalAllocateInteger /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg
+ o /r15 /rdx :movqMemDisp8Reg
+ /rdx 8 /rax :movqRegMemDisp8
+ } each
+
+ 48 /r15 :addqImm8Reg
+ /done :jmpLbl8
+
+ @failure
+
+ ::internalAllocateInteger /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg
+ 0 8 /rax :andqImm8MemDisp8
+
+ @done
+
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ]] /eyresolveInfo defv
> _ ==globalFunctions { defv }' ::allocateOffsetStruct
[
diff --git a/compiler/elymasGlobalSysOpt.ey b/compiler/elymasGlobalSysOpt.ey
index 01fb1c0..8275e51 100644
--- a/compiler/elymasGlobalSysOpt.ey
+++ b/compiler/elymasGlobalSysOpt.ey
@@ -4,7 +4,9 @@
<
# stub
# 0 -> code object
+ # 1 -> current scope
# 0 <- same code object (if different object, optimization would have taken place)
+ # 1 <- current scope (value ignored)
[[
:retn
]] /eyhook defv
diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey
index 87f2ab2..643a805 100644
--- a/compiler/standardClient.ey
+++ b/compiler/standardClient.ey
@@ -885,7 +885,7 @@
# %40 ==? section header size, %38 == program header size
metaSections len allocSections len add %40 mul
allocSections len %38 mul add
- %40 add ==dataOffset
+ %40 add ==?dataOffset
metaSections { ==s
dataOffset s .setDataOffset
dataOffset s .dataSize add =dataOffset
diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey
index 907b3fd..bd7600f 100644
--- a/elymas/lib/sys/opt.ey
+++ b/elymas/lib/sys/opt.ey
@@ -122,7 +122,109 @@
/r15 :popqMem
] ==:customFunctionHeaderPattern
- { ==o
+ /NOP ==:NOP
+ /PUSH ==:PUSH
+ /CALL ==:CALL
+ /CALLSCOPED ==:CALLSCOPED
+ /STATIC ==:STATIC
+ /STATICWRITE ==:STATICWRITE
+ /NATIVE ==:NATIVE
+
+ { =*f ==t
+ t { f } { 0 } ? *
+ } /andif deffd
+
+ { ==o ==executingScope
+ 0 ==containsScopeModifications # TODO: replace <, > by macros ( {, scope } * respectively) then remove this
+
+ { _ ==logic
+ logic { ==entry 0 entry * ==action
+ [
+ { action CALL streq { 1 entry * "<" | +rawCodeAddress eq }' andif }' {
+ 1 =containsScopeModifications
+ }
+
+ { action CALL streq { 1 entry * ">" | +rawCodeAddress eq }' andif }' {
+ 1 =containsScopeModifications
+ }
+ ] conds
+ } each
+ } /testScopeModifications deffst
+
+ { ==logic
+ [ /NOP ] ==last
+ [ logic { ==entry 0 entry * ==action
+ [
+ { action CALL streq { 1 entry * "|" | +rawCodeAddress eq }' andif { 0 last * PUSH streq }' andif }' {
+ 1 last * +rawObject ==constant
+
+ constant executingScope sys .resolveInfo {
+ ==mode -- ==parentCount 32 add ==offsetInScope ==inExtensionArea
+ inExtensionArea { offsetInScope 8 add =offsetInScope } rep
+
+ mode 16 div 1 band {
+ [ STATIC offsetInScope parentCount inExtensionArea ] =last
+ [ /NOP ] =entry
+ } { } ? *
+ } {
+ executingScope dump
+ executingScope keys dump
+ constant dump
+ "resolution failed" die
+ } ? *
+ }
+ ] conds
+
+ last
+ entry =last
+ } each last ]
+ } /rewriteConstantPipe deffst
+
+ { ==logic
+ [ /NOP ] ==last
+ [ logic { ==entry 0 entry * ==action
+ [
+ { action CALL streq { 1 entry * "=" | +rawCodeAddress eq }' andif { 0 last * PUSH streq }' andif }' {
+ 1 last * +rawObject ==constant
+
+ constant executingScope sys .resolveInfo {
+ ==mode -- ==parentCount 32 add ==offsetInScope ==inExtensionArea
+ inExtensionArea { offsetInScope 8 add =offsetInScope } rep
+
+ mode 16 div 1 band {
+ [ STATICWRITE offsetInScope parentCount inExtensionArea ] =last
+ [ /NOP ] =entry
+ } { } ? *
+ } {
+ executingScope dump
+ executingScope keys dump
+ constant dump
+ "resolution failed" die
+ } ? *
+ }
+ ] conds
+
+ last
+ entry =last
+ } each last ]
+ } /rewriteConstantEquals deffst
+
+ { ==logic
+ [ /NOP ] ==last
+ [ logic { ==entry 0 entry * ==action
+ [
+ { action CALL streq { 1 entry * "_" | +rawCodeAddress eq }' andif }' {
+ [ NATIVE [
+ 0 /rsp :pushqMemDisp8
+ ] ] =entry
+ }
+ ] conds
+
+ last
+ entry =last
+ } each last ]
+ } /rewriteStackOps deffst
+
sys .asm "+" via
sys .asm .|peek ==:peek
sys .opt "::" via
@@ -135,11 +237,6 @@
# "Code length: " dump codeLength dump
addr 16 add ==i
- [ ] ==newOpcodes
- { newOpcodes -01 cat =newOpcodes }' /emitOpcodes deffst
- [ ] ==newReferences
- { newReferences [ -102 ] cat =newReferences }' /emitReference deffst
-
{ =*ops =*set =*get ==pattern
1 ==found
get ==j
@@ -152,199 +249,87 @@
generalHeaderPattern match not { "failure while matching generalHeaderPattern" die }" rep
scopingHeaderPattern match ==isScoping
- # [ :ud2 ] emitOpcodes # enable for further development
-
- isScoping {
- # "scoping function" dump
- [
- 8 /r15 :subqImm8Reg
- /r15 :popqMem
- 8 /r15 :subqImm8Reg
- ::currentScope /rbx :movqImmReg
- /rbx /rsi :movqMemReg
- /rsi /r15 :movqRegMem
- 8 /rdi :movqImmReg
- ::internalAllocateScope /rax :movqImmReg
- /rax :callqReg
- /rax /rbx :movqRegMem
- ] emitOpcodes
- }" {
- # "unscoping function" dump
- [
- 8 /r15 :subqImm8Reg
- /r15 :popqMem
- ] emitOpcodes
- }" ? *
-
1 ==continueParsing
+ [ ] ==newLogic
+ { newLogic [ -102 ] cat =newLogic }' /emitLogic deffst
+
{ continueParsing }' { i ==s
[
{ footerPattern match }' {
- # "footerPattern matched" dump
0 =continueParsing
}
{ pushConstantPattern match }' {
- # "pushConstantPattern matched" dump
[ s 2 add _ 8 add range peek each ] 256 math .unbase ==pushedConstant
- # "pushedConstant: " dump pushedConstant dump
- [
- pushedConstant /rax :movqImmReg
- /rax :pushqReg
- ] emitOpcodes
-
- pushedConstant emitReference
+ [ PUSH pushedConstant ] emitLogic
}
{ callConstantPattern match }' {
- # "callConstantPattern matched" dump
[ s 2 add _ 8 add range peek each ] 256 math .unbase ==calledAddress
- # "calledAddress: " dump calledAddress dump
calledAddress ==j
{ { j }' { =j }' peek generalMatch }' /callTargetMatch deff
[
{ constantActiveGeneralPattern callTargetMatch }' {
- # "constantActiveGeneralPattern matched" dump
[ calledAddress 3 add _ 8 add range peek each ] 256 math .unbase ==calledConstant
- # "calledConstant: " dump calledConstant dump
- [
- calledConstant /rax :movqImmReg
- /rax :pushqReg
- "*" | +rawCodeAddress /rax :movqImmReg
- /rax :callqReg
- ] emitOpcodes
-
- calledConstant emitReference
+ [ PUSH calledConstant ] emitLogic
+ [ CALL "*" | +rawCodeAddress ] emitLogic
}
{ constantNormalFunctionScopedUntypedPattern callTargetMatch }' {
- # "constantNormalFunctionScopedUntypedPattern matched" dump
[ calledAddress 2 add _ 8 add range peek each ] 256 math .unbase ==functionScope
[ calledAddress 36 add _ 8 add range peek each ] 256 math .unbase ==finalAddress
- # "functionScope: " dump functionScope dump
- # "finalAddress: " dump finalAddress dump
-
- [
- functionScope /rsi :movqImmReg
- 8 /r15 :subqImm8Reg
- ::currentScope /rax :movqImmReg
- /rsi /rax :xchgqRegMem
- /rsi /r15 :movqRegMem
- finalAddress /rdi :movqImmReg
- /rdi :callqReg
-
- /r15 /rsi :movqMemReg
- ::currentScope /rax :movqImmReg
- /rsi /rax :movqRegMem
-
- 8 /r15 :addqImm8Reg
- ] emitOpcodes
-
- functionScope emitReference
- finalAddress 16 sub emitReference
+ [ CALLSCOPED finalAddress functionScope ] emitLogic
}
{ constantNormalFunctionUnscopedUntypedPattern callTargetMatch }' {
- # "constantNormalFunctionUnscopedUntypedPattern matched" dump
[ calledAddress 2 add _ 8 add range peek each ] 256 math .unbase ==finalAddress
- # "finalAddress: " dump finalAddress dump
- [
- finalAddress /rax :movqImmReg
- /rax :callqReg
- ] emitOpcodes
-
- finalAddress 16 sub emitReference
+ [ CALL finalAddress ] emitLogic
}
{ constantPassivePattern callTargetMatch }' {
- # "constantPassivePattern matched" dump
[ calledAddress 3 add _ 8 add range peek each ] 256 math .unbase ==pushedConstant
- # "pushedConstant: " dump pushedConstant dump
-
- [
- pushedConstant /rax :movqImmReg
- /rax :pushqReg
- ] emitOpcodes
- pushedConstant emitReference
+ [ PUSH pushedConstant ] emitLogic
}
{ staticLoadPattern callTargetMatch }' {
- # "staticLoadPattern matched" dump
-
- [
- ::currentScope /rax :movqImmReg
- /rax /rax :movqMemReg
- ] emitOpcodes
-
+ 0 ==parentCount
{ staticLoadParentPattern callTargetMatch }' {
- # "staticLoadParentPattern matched" dump
-
- [
- 16 /rax /rax :movqMemDisp8Reg
- ] emitOpcodes
+ parentCount 1 add =parentCount
} loop
j ==loadStart
[
{ staticLoadPassiveFromScopePattern callTargetMatch }' {
- # "staticLoadPassiveFromScopePattern" dump
[ loadStart 3 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
- # "loadStart: " dump loadStart dump
- # "offsetInScope: " dump offsetInScope dump
- [
- offsetInScope /rax :pushqMemDisp32
- ] emitOpcodes
+ [ STATIC offsetInScope parentCount 0 ] emitLogic
}
{ staticLoadPassiveFromExtensionPattern callTargetMatch }' {
- # "staticLoadPassiveFromExtensionPattern" dump
[ loadStart 13 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
- # "loadStart: " dump loadStart dump
- # "offsetInScope: " dump offsetInScope dump
- [
- 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer
- /rax /edx :movlMemReg # load scope length
- /rdx :negqReg # prepare for substraction
- offsetInScope 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack
- ] emitOpcodes
+ [ STATIC offsetInScope parentCount 1 ] emitLogic
}
{ staticLoadActiveFromScopePattern callTargetMatch }' {
- # "staticLoadActiveFromScopePattern" dump
[ loadStart 3 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
- # "loadStart: " dump loadStart dump
- # "offsetInScope: " dump offsetInScope dump
-
- [
- offsetInScope /rax :pushqMemDisp32
- "*" | +rawCodeAddress /rax :movqImmReg
- /rax :callqReg
- ] emitOpcodes
+
+ [ STATIC offsetInScope parentCount 0 ] emitLogic
+ [ CALL "*" | +rawCodeAddress ] emitLogic
}
{ staticLoadActiveFromExtensionPattern callTargetMatch }' {
- # "staticLoadActiveFromExtensionPattern" dump
[ loadStart 13 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
- # "loadStart: " dump loadStart dump
- # "offsetInScope: " dump offsetInScope dump
-
- [
- 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer
- /rax /edx :movlMemReg # load scope length
- /rdx :negqReg # prepare for substraction
- offsetInScope 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack
- "*" | +rawCodeAddress /rax :movqImmReg
- /rax :callqReg
- ] emitOpcodes
+
+ [ STATIC offsetInScope parentCount 1 ] emitLogic
+ [ CALL "*" | +rawCodeAddress ] emitLogic
}
{ 1 }' {
@@ -357,14 +342,7 @@
}
{ customFunctionHeaderPattern callTargetMatch }' {
- # "customFunctionHeaderPattern matched" dump
-
- [
- calledAddress /rax :movqImmReg
- /rax :callqReg
- ] emitOpcodes
-
- calledAddress 16 sub emitReference
+ [ CALL calledAddress ] emitLogic
}
{ 1 }' {
@@ -385,6 +363,130 @@
] conds
} loop
+ [ ] ==newOpcodes
+ { newOpcodes -01 cat =newOpcodes }' /emitOpcodes deffst
+ [ ] ==newReferences
+ { newReferences [ -102 ] cat =newReferences }' /emitReference deffst
+
+ # [ :ud2 ] emitOpcodes # enable for further development
+
+ isScoping {
+ # "scoping function" dump
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+ 8 /r15 :subqImm8Reg
+ ::currentScope /rbx :movqImmReg
+ /rbx /rsi :movqMemReg
+ /rsi /r15 :movqRegMem
+ 8 /rdi :movqImmReg
+ ::internalAllocateScope /rax :movqImmReg
+ /rax :callqReg
+ /rax /rbx :movqRegMem
+ ] emitOpcodes
+ }" {
+ # "unscoping function" dump
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+ ] emitOpcodes
+ }" ? *
+
+ newLogic
+ testScopeModifications
+ containsScopeModifications not |rewriteConstantPipe rep
+ containsScopeModifications not |rewriteConstantEquals rep
+ rewriteStackOps
+ { =*entry 0 entry ==action
+ [
+ { action PUSH streq }' {
+ [
+ 1 entry /rax :movqImmReg
+ /rax :pushqReg
+ ] emitOpcodes
+
+ 1 entry emitReference
+ }
+
+ { action CALL streq }' {
+ [
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+ ] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ }
+
+ { action CALLSCOPED streq }' {
+ [
+ 2 entry /rsi :movqImmReg
+ 8 /r15 :subqImm8Reg
+
+ ::currentScope /rax :movqImmReg
+ /rsi /rax :xchgqRegMem
+ /rsi /r15 :movqRegMem
+ 1 entry /rdi :movqImmReg
+ /rdi :callqReg
+
+ /r15 /rsi :movqMemReg
+ ::currentScope /rax :movqImmReg
+ /rsi /rax :movqRegMem
+
+ 8 /r15 :addqImm8Reg
+ ] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ 2 entry emitReference
+ }
+
+ { action STATIC streq }' {
+ [
+ ::currentScope /rax :movqImmReg
+ /rax /rax :movqMemReg
+ 2 entry { 16 /rax /rax :movqMemDisp8Reg } rep
+
+ 3 entry {
+ 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer
+ /rax /edx :movlMemReg # load scope length
+ /rdx :negqReg # prepare for substraction
+ 1 entry 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack
+ } {
+ 1 entry /rax :pushqMemDisp32
+ } ? *
+ ] emitOpcodes
+ }
+
+ { action STATICWRITE streq }' {
+ [
+ ::currentScope /rax :movqImmReg
+ /rax /rax :movqMemReg
+ 2 entry { 16 /rax /rax :movqMemDisp8Reg } rep
+
+ 3 entry {
+ 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer
+ /rax /edx :movlMemReg # load scope length
+ /rdx :negqReg # prepare for substraction
+ 1 entry 1 /rdx /rcx :popqMemIndexScaleDisp32 # load entry from stack
+ } {
+ 1 entry /rax :popqMemDisp32
+ } ? *
+ ] emitOpcodes
+ }
+
+ { action NATIVE streq }' {
+ 1 entry emitOpcodes
+ }
+
+ { action NOP streq }' {
+ }
+
+ { 1 }' {
+ entry dump
+ "invalid intermediate code during optimize" die
+ }
+ ] conds
+ } each
+
isScoping {
[
/r15 /rcx :movqMemReg
@@ -405,8 +507,16 @@
# "optimization finished" dump
- newReferences newOpcodes o ::replace
- 1 # return something different from o to signal successful optimization
+ newReferences newOpcodes o ::replace
+ 1 executingScope # return something different from o to signal successful optimization
+ } /optimize deffd
+
+ 0 ==recursionDepth
+
+ {
+ recursionDepth 1 add =recursionDepth
+ recursionDepth 3 lt { optimize } { } ? *
+ recursionDepth 1 sub =recursionDepth
} /hook sys .opt .deff
> --
diff --git a/elymas/optimized.ey b/elymas/optimized.ey
index c2961d4..ca53b40 100644
--- a/elymas/optimized.ey
+++ b/elymas/optimized.ey
@@ -5,4 +5,4 @@
"lib/sys/opt.ey"
] { _ dump include }' each
-{ "/proc/self/fd/0" include }' "optimized" sys .freeze
+2 { { "/proc/self/fd/0" include }' "optimized" sys .freeze } rep # FIXME freeze wonkyness (the optimizer allocates during freeze)