aboutsummaryrefslogtreecommitdiff
path: root/compiler/elymasGlobalSys.ey
blob: 68a30c9846d17a15319095406c25934b59b7a8c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<
  "sys" enterSubScope

  <
    # 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
    [[
      8 /r15 :subqImm8Reg
      /r15 :popqMem
      
      8 /r15 :subqImm8Reg
      /r14 /r15 :movqRegMem
      /r14 :popqReg # load scope from argument

      internalExecuteIdentifier /rax :movqImmReg
      /rax :callqReg

      /r14 :pushqReg
      /r15 /r14 :movqMemReg
      8 /r15 :addqImm8Reg

      /r15 :pushqMem
      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)
    # TODO simplify by returning unboxed ints where appropriate maybe
    [[
      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

    # return information about the captured scope of a function
    # 0 -> function object
    # 0 <- any scope captured
    # 1 <- if any scope was caputered, that scope
    [[
      8 /r15 :subqImm8Reg
      /r15 :popqMem

      /rsi :popqReg
      8 /rsi /rsi :movqMemDisp8Reg
      /rsi /rsi :testqRegReg
      /noScopeCaptured :jzLbl8

      /rsi :pushqReg # push scope
      1 /rax :movqImmReg
      63 /rax :btsqImm8Reg
      /rax :pushqReg

      /done :jmpLbl8

      @noScopeCaptured
      63 /rsi :btsqImm8Reg
      /rsi :pushqReg

      @done
      /r15 :pushqMem
      8 /r15 :addqImm8Reg
      :retn
    ]] /eycapturedScope defv
  > _ ==globalFunctions { defv }' ::allocateOffsetStruct

  [
    globalFunctions keys eydeff { | }' createScopeEntries
    createScopeExtensionEntries
  ] :execute

  "elymasGlobalSysAsm.ey" include
  "elymasGlobalSysOpt.ey" include
  "elymasGlobalSysDyn.ey" include
  "elymasGlobalSysTyped.ey" include

  leaveSubScope
> --

# vim: syn=elymas