From f9d0ff3becbe6835d32a146895d797d53a09fc15 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 18 Dec 2022 22:43:52 +0100 Subject: [PATCH] all: store data layout as little endian value This makes it much easier to read the value at runtime, as pointer indices are naturally little endian. It should not affect anything else in the program. --- compiler/llvm.go | 10 ++++++++++ compiler/testdata/gc.ll | 4 ++-- interp/memory.go | 10 ++++++++++ interp/testdata/alloc.ll | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/compiler/llvm.go b/compiler/llvm.go index 8b80869b..86c84319 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -166,6 +166,7 @@ func (c *compilerContext) createObjectLayout(t llvm.Type, pos token.Pos) llvm.Va // Create the global initializer. bitmapBytes := make([]byte, int(objectSizeWords+7)/8) bitmap.FillBytes(bitmapBytes) + reverseBytes(bitmapBytes) // big-endian to little-endian var bitmapByteValues []llvm.Value for _, b := range bitmapBytes { bitmapByteValues = append(bitmapByteValues, llvm.ConstInt(c.ctx.Int8Type(), uint64(b), false)) @@ -314,3 +315,12 @@ func (b *builder) readStackPointer() llvm.Value { } return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "") } + +// Reverse a slice of bytes. From the wiki: +// https://github.com/golang/go/wiki/SliceTricks#reversing +func reverseBytes(buf []byte) { + for i := len(buf)/2 - 1; i >= 0; i-- { + opp := len(buf) - 1 - i + buf[i], buf[opp] = buf[opp], buf[i] + } +} diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll index e54b207d..4044ae72 100644 --- a/compiler/testdata/gc.ll +++ b/compiler/testdata/gc.ll @@ -20,8 +20,8 @@ target triple = "wasm32-unknown-wasi" @main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 @main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 @main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 -@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c" \00\00\00\00\00\00\01" } -@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\00\00\00\00\00\00\00\01" } +@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " } +@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" } @"reflect/types.type:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:complex128", i32 0 } @"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:complex128", i32 0, ptr null, ptr null, i32 0 } diff --git a/interp/memory.go b/interp/memory.go index 248825f6..88b7783e 100644 --- a/interp/memory.go +++ b/interp/memory.go @@ -1289,6 +1289,7 @@ func (r *runner) readObjectLayout(layoutValue value) (uint64, *big.Int) { } rawBytes[i] = byte(v) } + reverseBytes(rawBytes) // little-endian to big-endian bitmap := new(big.Int).SetBytes(rawBytes) return objectSizeWords, bitmap } @@ -1338,3 +1339,12 @@ func (r *runner) getLLVMTypeFromLayout(layoutValue value) llvm.Type { } return llvmLayoutType } + +// Reverse a slice of bytes. From the wiki: +// https://github.com/golang/go/wiki/SliceTricks#reversing +func reverseBytes(buf []byte) { + for i := len(buf)/2 - 1; i >= 0; i-- { + opp := len(buf) - 1 - i + buf[i], buf[opp] = buf[opp], buf[i] + } +} diff --git a/interp/testdata/alloc.ll b/interp/testdata/alloc.ll index dd8819ef..28b0c84e 100644 --- a/interp/testdata/alloc.ll +++ b/interp/testdata/alloc.ll @@ -1,7 +1,7 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32--wasi" -@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c" \00\00\00\00\00\00\01" } +@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " } @pointerFree12 = global i8* null @pointerFree7 = global i8* null @pointerFree3 = global i8* null