diff options
author | Ayke van Laethem <[email protected]> | 2023-05-20 17:28:13 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-05-20 23:57:20 +0200 |
commit | 481f60c5ea3a06a295f6a34bcee5754563358e28 (patch) | |
tree | 26dc9103df4ac7ed4d118857cc68d798a701bc68 | |
parent | cf39db36fea07c7b35e50e47f6c76d4c3f15100e (diff) | |
download | tinygo-481f60c5ea3a06a295f6a34bcee5754563358e28.tar.gz tinygo-481f60c5ea3a06a295f6a34bcee5754563358e28.zip |
interp: add support for reading a pointer tag
This is necessary to get https://github.com/tinygo-org/tinygo/pull/3691
working.
-rw-r--r-- | interp/interpreter.go | 8 | ||||
-rw-r--r-- | interp/testdata/consteval.ll | 8 | ||||
-rw-r--r-- | interp/testdata/consteval.out.ll | 1 |
3 files changed, 17 insertions, 0 deletions
diff --git a/interp/interpreter.go b/interp/interpreter.go index 1ec4597e1..c48b9b5fe 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -746,6 +746,14 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // src/strings/builder.go in the Go source tree. This is // the identity operator, so we can return the input. locals[inst.localIndex] = lhs + } else if inst.opcode == llvm.And && rhs.Uint() < 8 { + // This is probably part of a pattern to get the lower bits + // of a pointer for pointer tagging, like this: + // uintptr(unsafe.Pointer(t)) & 0b11 + // We can actually support this easily by ANDing with the + // pointer offset. + result := uint64(lhsPtr.offset()) & rhs.Uint() + locals[inst.localIndex] = makeLiteralInt(result, int(lhs.len(r)*8)) } else { // Catch-all for weird operations that should just be done // at runtime. diff --git a/interp/testdata/consteval.ll b/interp/testdata/consteval.ll index 05d377f1b..3cbe7fcf7 100644 --- a/interp/testdata/consteval.ll +++ b/interp/testdata/consteval.ll @@ -4,6 +4,7 @@ target triple = "x86_64--linux" @intToPtrResult = global i8 0 @ptrToIntResult = global i8 0 @icmpResult = global i8 0 +@pointerTagResult = global i64 0 @someArray = internal global {i16, i8, i8} zeroinitializer @someArrayPointer = global ptr zeroinitializer @@ -17,6 +18,7 @@ define internal void @main.init() { call void @testPtrToInt() call void @testConstGEP() call void @testICmp() + call void @testPointerTag() ret void } @@ -63,3 +65,9 @@ unequal: ret void ret void } + +define internal void @testPointerTag() { + %val = and i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @someArray, i32 2) to i64), 3 + store i64 %val, ptr @pointerTagResult + ret void +} diff --git a/interp/testdata/consteval.out.ll b/interp/testdata/consteval.out.ll index 0d0b2884e..fff0e18f9 100644 --- a/interp/testdata/consteval.out.ll +++ b/interp/testdata/consteval.out.ll @@ -4,6 +4,7 @@ target triple = "x86_64--linux" @intToPtrResult = local_unnamed_addr global i8 2 @ptrToIntResult = local_unnamed_addr global i8 2 @icmpResult = local_unnamed_addr global i8 2 +@pointerTagResult = local_unnamed_addr global i64 2 @someArray = internal global { i16, i8, i8 } zeroinitializer @someArrayPointer = local_unnamed_addr global ptr getelementptr inbounds ({ i16, i8, i8 }, ptr @someArray, i64 0, i32 1) |