aboutsummaryrefslogtreecommitdiffhomepage
path: root/interp/interpreter.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2023-09-09 16:38:30 +0200
committerRon Evans <[email protected]>2023-09-10 11:30:09 +0200
commitf11731ff35efe573030896b499cfa8bd4d13e9dc (patch)
tree9ace32f9dec2fec7e88166e1bc308a89ea301735 /interp/interpreter.go
parente9d8a9bc0b433221a5fe242a18071ff60020baa4 (diff)
downloadtinygo-f11731ff35efe573030896b499cfa8bd4d13e9dc.tar.gz
tinygo-f11731ff35efe573030896b499cfa8bd4d13e9dc.zip
interp: don't copy unknown values in runtime.sliceCopy
This was bug https://github.com/tinygo-org/tinygo/issues/3890. See the diff for details. Essentially, it means that `copy` in the interpreter was copying data that wasn't known yet, or copying data into a slice that could be read externally after the interp pass.
Diffstat (limited to 'interp/interpreter.go')
-rw-r--r--interp/interpreter.go14
1 files changed, 14 insertions, 0 deletions
diff --git a/interp/interpreter.go b/interp/interpreter.go
index c48b9b5fe..8e5faf642 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -338,6 +338,20 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err != nil {
return nil, mem, r.errorAt(inst, err)
}
+ if mem.hasExternalStore(src) || mem.hasExternalLoadOrStore(dst) {
+ // These are the same checks as there are on llvm.Load
+ // and llvm.Store in the interpreter. Copying is
+ // essentially loading from the source array and storing
+ // to the destination array, hence why we need to do the
+ // same checks here.
+ // This fixes the following bug:
+ // https://github.com/tinygo-org/tinygo/issues/3890
+ err := r.runAtRuntime(fn, inst, locals, &mem, indent)
+ if err != nil {
+ return nil, mem, err
+ }
+ continue
+ }
nBytes := uint32(n * elemSize)
dstObj := mem.getWritable(dst.index())
dstBuf := dstObj.buffer.asRawValue(r)