0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 94 p_filesz: 0x00011E02, (size in bytes of the segment in the file)
0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, # 102 p_memsz: 0x7FC00000, (size in bytes of the segment in memory)
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 112
-
-# 0x48, 0xc7, 0xc0, 0x3C, 0x00, 0x00, 0x00, # mov $0x3c,%rax
-# 0x48, 0x31, 0xff, # xor %rdi,%rdi
-# 0x0f, 0x05, # syscall
]
-Word = Struct.new(:name, :flags, :code)
+Word = Struct.new(:name, :addr, :flags, :code)
IMM = 1
class Integer
def do_word(code); code.each{|w| w.call() }; end
def word(name, flags, code)
code = code.map{|w| $words[w].code }
- $words[name] = Word.new(name, flags, lambda { do_word(code) })
+ $words[name] = Word.new(name, nil, flags, lambda { do_word(code) })
end
def builtin(name, &code)
- $words[name] = Word.new(name, 0, code)
+ $words[name] = Word.new(name, nil, 0, code)
end
def call(word)
end
builtin('variable') do
- offset = base_offset()
call('word')
name = pop()
- allocation = (3 + ((name.length + 1) / 8.0).ceil) * 8
- value_addr = (offset + PROG.length)
- code_addr = offset + (allocation * 8)
+ # allocate value slot
+ pack64(0)
+
+ offset = base_offset()
+ here = PROG.length
+
+ allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8
+ value_addr = (here - 8)
+ code_addr = here + allocation
+
+ pack64(code_addr) # CODE ADDR
+ if $words['latest']
+ pack64($words['latest'].addr)
+ else
+ pack64(0)
+ end
- pack64(0) # VALUE
- pack64(code_addr) # CODE ADDR
- pack64(0) # LINK - TODO: actually link to latest
- pack8(name.length) # NAME LEN
- packBytes(name.bytes) # NAME
+ pack8(name.length) # NAME LEN
+ packBytes(name.bytes) # NAME
packPadding(PROG.length % 8)
mov_imm(value_addr, 0) # load address
packBytes([0x48, 0x8D, 0x6D, 0x08]) # lea 0x8(%rbp),%rbp
packBytes([0x48, 0x89, 0x45, 0x00]) # mov %rax,(%rbp)
packPadding(PROG.length % 8)
+
+ $words[name] = Word.new(name, here + offset, 0, 0)
+ $words['latest'].addr = here + offset
end
builtin('code') do
- offset = base_offset()
call('word')
name = pop()
+ offset = base_offset()
+ here = PROG.length
+
allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8
- code_addr = offset + (allocation * 8)
+ value_addr = (here - 8)
+ code_addr = here + allocation
- pack64(code_addr) # CODE ADDR
- pack64(0) # LINK - TODO: actually link to latest
- pack8(name.length) # NAME LEN
- packBytes(name.bytes) # NAME
+ pack64(code_addr) # CODE ADDR
+ if $words['latest']
+ pack64($words['latest'].addr)
+ else
+ pack64(0)
+ end
+
+ pack8(name.length) # NAME LEN
+ packBytes(name.bytes) # NAME
packPadding(PROG.length % 8)
+
+ $words[name] = Word.new(name, here + offset, 0, 0)
+ $words['latest'].addr = here + offset
end
builtin('end-code') do