diff --git a/src/asmc/compile.go b/src/asmc/compile.go index dfcddca..41169c9 100644 --- a/src/asmc/compile.go +++ b/src/asmc/compile.go @@ -121,7 +121,7 @@ func (c *compiler) compile(x asm.Instruction) { case asm.PUSH: switch operands := x.Data.(type) { case *asm.Number: - c.code = x86.PushNumber(c.code, operands.Number) + c.code = x86.PushNumber(c.code, int32(operands.Number)) case *asm.Register: c.code = x86.PushRegister(c.code, operands.Register) } diff --git a/src/core/CallExtern.go b/src/core/CallExtern.go index 588761f..241c15a 100644 --- a/src/core/CallExtern.go +++ b/src/core/CallExtern.go @@ -1,7 +1,6 @@ package core import ( - "fmt" "slices" "git.urbach.dev/cli/q/src/asm" @@ -37,7 +36,7 @@ func (f *Function) CallExtern(fn *Function, parameters []*expression.Expression) f.Number(asm.PUSH, 0) f.Number(asm.PUSH, 0) f.RegisterNumber(asm.SUB, x86.RSP, 32) - f.DLLCall(fmt.Sprintf("%s.%s", fn.Package, fn.Name)) + f.DLLCall(fn.UniqueName) f.RegisterRegister(asm.MOVE, x86.RSP, x86.RBP) f.Register(asm.POP, x86.RBP) diff --git a/src/data/Finalize.go b/src/data/Finalize.go index b890ae0..aa0787a 100644 --- a/src/data/Finalize.go +++ b/src/data/Finalize.go @@ -9,19 +9,22 @@ import ( // It will try to reuse existing data whenever possible. func (data Data) Finalize() ([]byte, map[string]int32) { var ( - final []byte keys = make([]string, 0, len(data)) positions = make(map[string]int32, len(data)) + capacity = 0 ) - for key := range data { + for key, value := range data { keys = append(keys, key) + capacity += len(value) } sort.SliceStable(keys, func(i, j int) bool { return len(data[keys[i]]) > len(data[keys[j]]) }) + final := make([]byte, 0, capacity) + for _, key := range keys { raw := data[key] position := bytes.Index(final, raw) diff --git a/src/data/bench_test.go b/src/data/bench_test.go new file mode 100644 index 0000000..3c6987e --- /dev/null +++ b/src/data/bench_test.go @@ -0,0 +1,21 @@ +package data_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/data" +) + +func BenchmarkFinalize(b *testing.B) { + d := data.Data{} + d.Insert("1", []byte("Beautiful is better than ugly.")) + d.Insert("2", []byte("Explicit is better than implicit.")) + d.Insert("3", []byte("Simple is better than complex.")) + d.Insert("4", []byte("Complex is better than complicated.")) + d.Insert("5", []byte("Flat is better than nested.")) + d.Insert("6", []byte("Sparse is better than dense.")) + + for b.Loop() { + d.Finalize() + } +} diff --git a/src/x86/Push.go b/src/x86/Push.go index 9a2c233..0ef49e8 100644 --- a/src/x86/Push.go +++ b/src/x86/Push.go @@ -6,13 +6,9 @@ import ( ) // PushNumber pushes a number onto the stack. -func PushNumber(code []byte, number int) []byte { +func PushNumber(code []byte, number int32) []byte { length := sizeof.Signed(number) - if length >= 8 { - panic("x86 does not support pushing 64-bit numbers") - } - if length >= 2 { return append( code, diff --git a/src/x86/Push_test.go b/src/x86/Push_test.go index 30f1a68..138478d 100644 --- a/src/x86/Push_test.go +++ b/src/x86/Push_test.go @@ -10,7 +10,7 @@ import ( func TestPushNumber(t *testing.T) { usagePatterns := []struct { - Number int + Number int32 Code []byte }{ {0, []byte{0x6A, 0x00}},