Skip to content

Commit e6d6fc0

Browse files
2 parents c3baa5a + 4b9ccd4 commit e6d6fc0

13 files changed

Lines changed: 374 additions & 205 deletions

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ reasm
44
.DS_Store
55
bench
66
sourcemap.json
7-
*.c
87
main.*
98
!main.go
109
platform.info

compiler/boilerplate.luau

Lines changed: 11 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -19,94 +19,12 @@ local stdout_cache: string = ""
1919
local fflags: number = 0 -- floating-point exception flags (NV,DZ,OF,UF,NX)
2020

2121
-- Utility
22-
--- 32-bit helpers
23-
local function u32(v: number): number
24-
local n = math.floor(v % 0x100000000)
25-
if n < 0 then
26-
n += 0x100000000
27-
end
28-
return n
29-
end
30-
local function i32(v)
31-
local n = u32(v)
32-
if n >= 0x80000000 then
33-
return n - 0x100000000
34-
end
35-
return n
36-
end
37-
local function f32(v: number): number
38-
buffer.writef32(temp, 0, v)
39-
return buffer.readf32(temp, 0)
40-
end
41-
4222
--- Base (can be found in generated code)
43-
local function idiv_trunc(a: number, b: number): number
44-
if b == 0 then error("division by zero") end
45-
if a >= 0 then
46-
return (a - (a % b)) // b
47-
else
48-
return -((-a) - ((-a) % b)) // b
49-
end
50-
end
51-
local function float_to_int(f: number): number
52-
buffer.writef32(temp, 0, f)
53-
return buffer.readi32(temp, 0)
54-
end
55-
local function int_to_float(i: number): number
56-
buffer.writei32(temp, 0, i)
57-
return buffer.readf32(temp, 0)
58-
end
59-
local function float_to_double(f: number): number
60-
buffer.writef32(temp, 0, f)
61-
buffer.writei32(temp, 4, 0)
62-
return buffer.readf64(temp, 0)
63-
end
6423
local function two_words_to_double(highWord: number, lowWord: number): number
65-
buffer.writei32(temp, 0, u32(lowWord))
66-
buffer.writei32(temp, 4, u32(highWord))
24+
buffer.writei32(temp, 0, ((math.floor(lowWord % 0x100000000) + 0x100000000) % 0x100000000))
25+
buffer.writei32(temp, 4, ((math.floor(highWord % 0x100000000) + 0x100000000) % 0x100000000))
6726
return buffer.readf64(temp, 0)
6827
end
69-
local function hi(addr: number): number
70-
return bit32.lshift(bit32.rshift(addr, 12), 12)
71-
end
72-
local function lo(addr: number): number
73-
return bit32.band(addr, 0xFFF)
74-
end
75-
function fclass(x: number): number
76-
local result = 0
77-
78-
if x ~= x then
79-
result = bit32.bor(result, bit32.lshift(1, 9)) -- qNaN (cannot distinguish sNaN in Luau)
80-
elseif x == math.huge then
81-
result = bit32.bor(result, bit32.lshift(1, 7)) -- +Inf
82-
elseif x == -math.huge then
83-
result = bit32.bor(result, bit32.lshift(1, 0)) -- -Inf
84-
elseif x == 0 then
85-
if 1/x == -math.huge then
86-
result = bit32.bor(result, bit32.lshift(1, 3)) -- -Zero
87-
else
88-
result = bit32.bor(result, bit32.lshift(1, 4)) -- +Zero
89-
end
90-
else
91-
local absx = math.abs(x)
92-
local min_normal = 2.2250738585072014e-308 -- 2^-1022
93-
if absx < min_normal then
94-
if x > 0 then
95-
result = bit32.bor(result, bit32.lshift(1, 5)) -- +Subnormal
96-
else
97-
result = bit32.bor(result, bit32.lshift(1, 2)) -- -Subnormal
98-
end
99-
else
100-
if x > 0 then
101-
result = bit32.bor(result, bit32.lshift(1, 6)) -- +Normal
102-
else
103-
result = bit32.bor(result, bit32.lshift(1, 1)) -- -Normal
104-
end
105-
end
106-
end
107-
108-
return result
109-
end
11028
function reset_registers(): ()
11129
r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
11230
r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
@@ -136,11 +54,13 @@ function format_string(fmt: number, args: {number}): string
13654
if spec:sub(-1) == "d" then
13755
local val = args[arg_index]
13856
arg_index += 1
139-
return string.format("%"..fmtSpec, i32(val))
57+
58+
local n = --[[u32]] ((math.floor(val % 0x100000000) + 0x100000000) % 0x100000000);
59+
return string.format("%"..fmtSpec, --[[i32]] (n >= 0x80000000) and (n - 0x100000000) or n)
14060
elseif spec:sub(-1) == "X" then
14161
local val = args[arg_index]
14262
arg_index += 1
143-
return string.format("%"..fmtSpec, u32(val))
63+
return string.format("%"..fmtSpec, --[[u32]]((math.floor(val % 0x100000000) + 0x100000000) % 0x100000000))
14464
elseif spec:sub(-1) == "f" then
14565
if arg_index % 2 == 1 then
14666
arg_index += 1 -- 64-bit varargs are aligned to even a-registers (skip a1/a3/...)
@@ -168,12 +88,6 @@ function format_string(fmt: number, args: {number}): string
16888
end
16989

17090

171-
--- Memory
172-
local function malloc(size: number): number
173-
mallocDepth+=size
174-
return buffer.len(memory)-mallocDepth
175-
end
176-
17791
--- Args
17892
local function get_args(): (number, number, number, number, number, number, number, number)
17993
return r11, r12, r13, r14, r15, r16, r17, r18
@@ -209,56 +123,14 @@ local function flush_stdout()
209123
stdout_cache = ""
210124
end
211125
end
126+
local function malloc(size: number): number
127+
mallocDepth += size
128+
return buffer.len(memory) - mallocDepth
129+
end
212130

213131

214132
-- Functions
215-
local functions = {
216-
["memcpy"] = function()
217-
local dest,src,count = get_args()
218-
219-
buffer.copy(memory, dest, memory, src, count)
220-
end,
221-
["memset"] = function()
222-
local dest, value, count = get_args()
223-
buffer.fill(memory, dest, bit32.band(value, 0xFF), count)
224-
end,
225-
["malloc"] = function()
226-
local size = get_args()
227-
local dest = malloc(size)
228-
229-
push_args(dest)
230-
end,
231-
["putchar"] = function()
232-
local c = get_args()
233-
local char = string.char(c)
234-
if char == "\n" then
235-
flush_stdout()
236-
else
237-
stdout_cache = stdout_cache .. char
238-
end
239-
end,
240-
["puts"] = function()
241-
local fmt = get_args()
242-
local str = read_string(fmt)
243-
stdout_cache = stdout_cache .. str
244-
flush_stdout()
245-
end,
246-
["printf"] = function()
247-
local args = {get_args()}
248-
local fmt_ptr = args[1]
249-
table.remove(args, 1)
250-
251-
local formatted = format_string(fmt_ptr, args)
252-
for i = 1, #formatted do
253-
local ch = formatted:sub(i,i)
254-
if ch == "\n" then
255-
flush_stdout()
256-
else
257-
stdout_cache = stdout_cache .. ch
258-
end
259-
end
260-
end,
261-
}
133+
local functions = {}
262134

263135
local syscalls: {[number]: () -> ()} = {}
264136

compiler/compilation.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,16 +362,10 @@ func AfterCompilation(writer *OutputWriter) []byte {
362362
push_args = push_args,
363363
get_f_args = get_f_args,
364364
push_f_args = push_f_args,
365-
int_to_float = int_to_float,
366-
float_to_int = float_to_int,
367-
hi = hi,
368-
lo = lo,
369365
read_string = read_string,
370366
format_string = format_string,
371367
malloc = malloc,
372-
float_to_double = float_to_double,
373368
two_words_to_double = two_words_to_double,
374-
fclass = fclass,
375369
reset_registers = reset_registers,
376370
},
377371

compiler/extensions.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,38 @@ import (
1010
//go:embed math.luau
1111
var math_extension string
1212

13+
//go:embed memory.luau
14+
var memory_extension string
15+
16+
//go:embed stdio.luau
17+
var stdio_extension string
18+
19+
//go:embed stdlib.luau
20+
var stdlib_extension string
21+
1322
var extensions = map[string]string{
14-
"math": math_extension,
23+
"math": math_extension,
24+
"memory": memory_extension,
25+
"stdio": stdio_extension,
26+
"stdlib": stdlib_extension,
1527
}
1628

1729
func generateExtensions(writer *OutputWriter) string {
1830
var sb strings.Builder
19-
includesMath := false
31+
included := map[string]bool{}
2032

2133
for _, name := range writer.Options.Imports {
22-
if name == "math" {
23-
includesMath = true
24-
}
2534
if ext, ok := extensions[name]; ok {
35+
if included[name] {
36+
continue
37+
}
2638
sb.WriteString(ext)
2739
sb.WriteString("\n")
40+
included[name] = true
2841
} else {
2942
logrus.Warnf("unknown import: %s", name)
3043
}
3144
}
3245

33-
if !includesMath {
34-
sb.WriteString(math_extension)
35-
sb.WriteString("\n")
36-
}
37-
3846
return sb.String()
3947
}

0 commit comments

Comments
 (0)