Skip to content

Commit 8e1a8ff

Browse files
Adding unsafe.Slice
1 parent 0bee75b commit 8e1a8ff

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

compiler/expressions.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,10 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
10711071
case "Offsetof":
10721072
sel, _ := fc.selectionOf(astutil.RemoveParens(args[0]).(*ast.SelectorExpr))
10731073
return fc.formatExpr("%d", typesutil.OffsetOf(sizes32, sel))
1074+
case "Slice":
1075+
ptrType := fc.typeOf(args[0]).Underlying().(*types.Pointer)
1076+
sliceType := types.NewSlice(ptrType.Elem())
1077+
return fc.formatExpr("$unsafeSlice(%e, %e, %s)", args[0], args[1], fc.typeName(sliceType))
10741078
case "SliceData":
10751079
t := fc.typeOf(args[0]).Underlying().(*types.Slice)
10761080
return fc.formatExpr(`$sliceData(%e, %s)`, args[0], fc.typeName(t))

compiler/prelude/prelude.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,20 @@ var $typeOf = x => {
620620
return typeof (x);
621621
};
622622

623+
var $unsafeSlice = (ptr, len, typ) => {
624+
if (ptr === typ.nil || ptr.$isNil) {
625+
if (len > 0) {
626+
$throwRuntimeError("unsafe.Slice: ptr is nil and len is not zero");
627+
}
628+
return typ.nil;
629+
}
630+
var s = new typ(ptr.$target);
631+
s.$offset = ptr.$index;
632+
s.$length = len;
633+
s.$capacity = len;
634+
return s;
635+
};
636+
623637
var $sliceData = (slice, typ) => {
624638
if (slice === typ.nil) {
625639
return $ptrType(typ.elem).nil;

compiler/prelude/types.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,22 @@ var $indexPtr = (array, index, constructor) => {
656656
// Pointers of different primitive types are non-comparable and stored in different caches.
657657
var typeCache = cache[array.name] = cache[array.name] || {};
658658
var cacheIdx = array.BYTES_PER_ELEMENT * index + array.byteOffset;
659-
return typeCache[cacheIdx] || (typeCache[cacheIdx] = new constructor(() => { return array[index]; }, v => { array[index] = v; }));
659+
var ptr = typeCache[cacheIdx];
660+
if (!ptr) {
661+
ptr = new constructor(() => { return array[index]; }, v => { array[index] = v; }, array);
662+
ptr.$index = index;
663+
typeCache[cacheIdx] = ptr;
664+
}
665+
return ptr;
660666
} else {
661667
array.$ptr = array.$ptr || {};
662-
return array.$ptr[index] || (array.$ptr[index] = new constructor(() => { return array[index]; }, v => { array[index] = v; }));
668+
var ptr = array.$ptr[index];
669+
if (!ptr) {
670+
ptr = new constructor(() => { return array[index]; }, v => { array[index] = v; }, array);
671+
ptr.$index = index;
672+
array.$ptr[index] = ptr;
673+
}
674+
return ptr;
663675
}
664676
};
665677

0 commit comments

Comments
 (0)