mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 12:59:04 +00:00
interp: fix copy() from/to external buffers
This includes copying from a //go:embed slice for example. The slice with data is not available at interp time. See: https://github.com/tinygo-org/tinygo/issues/4895
This commit is contained in:
committed by
Ron Evans
parent
704489ed6d
commit
cb5f7ad3fd
+14
-1
@@ -364,9 +364,22 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
nBytes := uint32(n * elemSize)
|
nBytes := uint32(n * elemSize)
|
||||||
|
srcObj := mem.get(src.index())
|
||||||
dstObj := mem.getWritable(dst.index())
|
dstObj := mem.getWritable(dst.index())
|
||||||
|
if srcObj.buffer == nil || dstObj.buffer == nil {
|
||||||
|
// If the buffer is nil, it means the slice is external.
|
||||||
|
// This can happen for example when copying data out of
|
||||||
|
// a //go:embed slice, which is not available at interp
|
||||||
|
// time.
|
||||||
|
// See: https://github.com/tinygo-org/tinygo/issues/4895
|
||||||
|
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, mem, err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
dstBuf := dstObj.buffer.asRawValue(r)
|
dstBuf := dstObj.buffer.asRawValue(r)
|
||||||
srcBuf := mem.get(src.index()).buffer.asRawValue(r)
|
srcBuf := srcObj.buffer.asRawValue(r)
|
||||||
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
|
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
|
||||||
dstObj.buffer = dstBuf
|
dstObj.buffer = dstBuf
|
||||||
mem.put(dst.index(), dstObj)
|
mem.put(dst.index(), dstObj)
|
||||||
|
|||||||
Vendored
+18
@@ -11,6 +11,10 @@ target triple = "x86_64--linux"
|
|||||||
@main.sliceDstUntaint.buf = internal global [2 x i8] zeroinitializer
|
@main.sliceDstUntaint.buf = internal global [2 x i8] zeroinitializer
|
||||||
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
||||||
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
|
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceSrcExternal1.buf = external global [2 x i8]
|
||||||
|
@main.sliceDstExternal1.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceSrcExternal2.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceDstExternal2.buf = external global [2 x i8]
|
||||||
|
|
||||||
declare i64 @runtime.sliceCopy(ptr %dst, ptr %src, i64 %dstLen, i64 %srcLen, i64 %elemSize) unnamed_addr
|
declare i64 @runtime.sliceCopy(ptr %dst, ptr %src, i64 %dstLen, i64 %srcLen, i64 %elemSize) unnamed_addr
|
||||||
|
|
||||||
@@ -58,6 +62,14 @@ entry:
|
|||||||
%sliceDstTaint.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstTaint.buf, i32 0)
|
%sliceDstTaint.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstTaint.buf, i32 0)
|
||||||
call void @runtime.printuint8(i8 %sliceDstTaint.val)
|
call void @runtime.printuint8(i8 %sliceDstTaint.val)
|
||||||
|
|
||||||
|
; print(sliceDstExternal1[0])
|
||||||
|
%sliceDstExternal1.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstExternal1.buf, i32 0)
|
||||||
|
call void @runtime.printuint8(i8 %sliceDstExternal1.val)
|
||||||
|
|
||||||
|
; print(sliceDstExternal2[0])
|
||||||
|
%sliceDstExternal2.val = load i8, ptr getelementptr inbounds (i8, ptr @main.sliceDstExternal2.buf, i32 0)
|
||||||
|
call void @runtime.printuint8(i8 %sliceDstExternal2.val)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,5 +114,11 @@ entry:
|
|||||||
call void @use(ptr @main.sliceSrcTaint.buf)
|
call void @use(ptr @main.sliceSrcTaint.buf)
|
||||||
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
|
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
|
||||||
|
|
||||||
|
; Test that copying from or into external buffers works correctly.
|
||||||
|
; These copy operations must be done at runtime.
|
||||||
|
; https://github.com/tinygo-org/tinygo/issues/4895
|
||||||
|
%copy.n5 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal1.buf, ptr @main.sliceSrcExternal1.buf, i64 2, i64 2, i64 1)
|
||||||
|
%copy.n6 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal2.buf, ptr @main.sliceSrcExternal2.buf, i64 2, i64 2, i64 1)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+10
@@ -3,6 +3,10 @@ target triple = "x86_64--linux"
|
|||||||
|
|
||||||
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
@main.sliceSrcTaint.buf = internal global [2 x i8] c"cd"
|
||||||
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
|
@main.sliceDstTaint.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceSrcExternal1.buf = external global [2 x i8]
|
||||||
|
@main.sliceDstExternal1.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceSrcExternal2.buf = internal global [2 x i8] zeroinitializer
|
||||||
|
@main.sliceDstExternal2.buf = external global [2 x i8]
|
||||||
|
|
||||||
declare i64 @runtime.sliceCopy(ptr, ptr, i64, i64, i64) unnamed_addr
|
declare i64 @runtime.sliceCopy(ptr, ptr, i64, i64, i64) unnamed_addr
|
||||||
|
|
||||||
@@ -16,6 +20,8 @@ define void @runtime.initAll() unnamed_addr {
|
|||||||
entry:
|
entry:
|
||||||
call void @use(ptr @main.sliceSrcTaint.buf)
|
call void @use(ptr @main.sliceSrcTaint.buf)
|
||||||
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
|
%copy.n4 = call i64 @runtime.sliceCopy(ptr @main.sliceDstTaint.buf, ptr @main.sliceSrcTaint.buf, i64 2, i64 2, i64 1)
|
||||||
|
%copy.n5 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal1.buf, ptr @main.sliceSrcExternal1.buf, i64 2, i64 2, i64 1)
|
||||||
|
%copy.n6 = call i64 @runtime.sliceCopy(ptr @main.sliceDstExternal2.buf, ptr @main.sliceSrcExternal2.buf, i64 2, i64 2, i64 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,5 +34,9 @@ entry:
|
|||||||
call void @runtime.printuint8(i8 97)
|
call void @runtime.printuint8(i8 97)
|
||||||
%sliceDstTaint.val = load i8, ptr @main.sliceDstTaint.buf, align 1
|
%sliceDstTaint.val = load i8, ptr @main.sliceDstTaint.buf, align 1
|
||||||
call void @runtime.printuint8(i8 %sliceDstTaint.val)
|
call void @runtime.printuint8(i8 %sliceDstTaint.val)
|
||||||
|
%sliceDstExternal1.val = load i8, ptr @main.sliceDstExternal1.buf, align 1
|
||||||
|
call void @runtime.printuint8(i8 %sliceDstExternal1.val)
|
||||||
|
%sliceDstExternal2.val = load i8, ptr @main.sliceDstExternal2.buf, align 1
|
||||||
|
call void @runtime.printuint8(i8 %sliceDstExternal2.val)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user