diff options
author | Ayke van Laethem <[email protected]> | 2023-09-09 16:38:30 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-09-10 11:30:09 +0200 |
commit | f11731ff35efe573030896b499cfa8bd4d13e9dc (patch) | |
tree | 9ace32f9dec2fec7e88166e1bc308a89ea301735 /interp/interpreter.go | |
parent | e9d8a9bc0b433221a5fe242a18071ff60020baa4 (diff) | |
download | tinygo-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.go | 14 |
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) |