Skip to content

Commit eeb8a8f

Browse files
committed
Make sure temp locals don't collide when allocating literal arrays, fixes AssemblyScript#281
Originally part of AssemblyScript#288
1 parent db0e82f commit eeb8a8f

File tree

10 files changed

+513
-60
lines changed

10 files changed

+513
-60
lines changed

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6484,7 +6484,7 @@ export class Compiler extends DiagnosticEmitter {
64846484
}
64856485
var nativeArrayType = arrayType.toNativeType();
64866486
var currentFunction = this.currentFunction;
6487-
var tempLocal = currentFunction.getTempLocal(arrayType, false);
6487+
var tempLocal = currentFunction.addLocal(arrayType); // can't reuse a temp (used in compiledValues)
64886488
var stmts = new Array<ExpressionRef>(2 + length);
64896489
var index = 0;
64906490
stmts[index++] = module.createSetLocal(tempLocal.index,
@@ -6502,7 +6502,7 @@ export class Compiler extends DiagnosticEmitter {
65026502
}
65036503
assert(index + 1 == stmts.length);
65046504
stmts[index] = module.createGetLocal(tempLocal.index, nativeArrayType);
6505-
currentFunction.freeTempLocal(tempLocal);
6505+
currentFunction.freeTempLocal(tempLocal); // but can be reused now
65066506
this.currentType = arrayType;
65076507
return module.createBlock(null, stmts, nativeArrayType);
65086508
}

std/portable/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ declare class Map<K,V> {
354354
entries(): Iterable<[K, V]>;
355355
keys(): Iterable<K>;
356356
values(): Iterable<V>;
357+
delete(key: K): bool;
357358
[Symbol.iterator](): Iterator<[K,V]>;
358359
}
359360

tests/compiler/std/array-literal.optimized.wat

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
(type $ii (func (param i32) (result i32)))
55
(type $iiiv (func (param i32 i32 i32)))
66
(type $v (func))
7-
(type $FUNCSIG$i (func (result i32)))
87
(type $FUNCSIG$vii (func (param i32 i32)))
8+
(type $FUNCSIG$i (func (result i32)))
99
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
1010
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
1111
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
1212
(global $std/array-literal/emptyArrayI32 (mut i32) (i32.const 128))
1313
(global $std/array-literal/i (mut i32) (i32.const 0))
1414
(global $std/array-literal/dynamicArrayI8 (mut i32) (i32.const 0))
1515
(global $std/array-literal/dynamicArrayI32 (mut i32) (i32.const 0))
16+
(global $std/array-literal/dynamicArrayRef (mut i32) (i32.const 0))
17+
(global $std/array-literal/dynamicArrayRefWithCtor (mut i32) (i32.const 0))
1618
(memory $0 1)
1719
(data (i32.const 8) "\03")
1820
(data (i32.const 17) "\01\02")
@@ -206,9 +208,9 @@
206208
)
207209
(get_local $1)
208210
)
209-
(func $~lib/memory/memory.allocate (; 6 ;) (; has Stack IR ;) (type $FUNCSIG$i) (result i32)
211+
(func $~lib/memory/memory.allocate (; 6 ;) (; has Stack IR ;) (type $ii) (param $0 i32) (result i32)
210212
(call $~lib/allocator/arena/__memory_allocate
211-
(i32.const 8)
213+
(get_local $0)
212214
)
213215
)
214216
(func $~lib/internal/memory/memset (; 7 ;) (; has Stack IR ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
@@ -526,7 +528,9 @@
526528
)
527529
(i32.store
528530
(tee_local $0
529-
(call $~lib/memory/memory.allocate)
531+
(call $~lib/memory/memory.allocate
532+
(i32.const 8)
533+
)
530534
)
531535
(i32.const 0)
532536
)
@@ -572,7 +576,9 @@
572576
)
573577
(i32.store
574578
(tee_local $0
575-
(call $~lib/memory/memory.allocate)
579+
(call $~lib/memory/memory.allocate
580+
(i32.const 8)
581+
)
576582
)
577583
(i32.const 0)
578584
)
@@ -611,7 +617,12 @@
611617
(get_local $2)
612618
)
613619
)
614-
(func $start (; 12 ;) (; has Stack IR ;) (type $v)
620+
(func $std/array-literal/RefWithCtor#constructor (; 12 ;) (; has Stack IR ;) (type $FUNCSIG$i) (result i32)
621+
(call $~lib/memory/memory.allocate
622+
(i32.const 0)
623+
)
624+
)
625+
(func $start (; 13 ;) (; has Stack IR ;) (type $v)
615626
(local $0 i32)
616627
(set_global $~lib/allocator/arena/startOffset
617628
(i32.const 232)
@@ -990,8 +1001,88 @@
9901001
(unreachable)
9911002
)
9921003
)
1004+
(call $~lib/array/Array<i32>#__unchecked_set
1005+
(tee_local $0
1006+
(call $~lib/array/Array<i32>#constructor)
1007+
)
1008+
(i32.const 0)
1009+
(call $~lib/memory/memory.allocate
1010+
(i32.const 0)
1011+
)
1012+
)
1013+
(call $~lib/array/Array<i32>#__unchecked_set
1014+
(get_local $0)
1015+
(i32.const 1)
1016+
(call $~lib/memory/memory.allocate
1017+
(i32.const 0)
1018+
)
1019+
)
1020+
(call $~lib/array/Array<i32>#__unchecked_set
1021+
(get_local $0)
1022+
(i32.const 2)
1023+
(call $~lib/memory/memory.allocate
1024+
(i32.const 0)
1025+
)
1026+
)
1027+
(set_global $std/array-literal/dynamicArrayRef
1028+
(get_local $0)
1029+
)
1030+
(if
1031+
(i32.ne
1032+
(i32.load offset=4
1033+
(get_global $std/array-literal/dynamicArrayRef)
1034+
)
1035+
(i32.const 3)
1036+
)
1037+
(block
1038+
(call $~lib/env/abort
1039+
(i32.const 0)
1040+
(i32.const 32)
1041+
(i32.const 36)
1042+
(i32.const 0)
1043+
)
1044+
(unreachable)
1045+
)
1046+
)
1047+
(call $~lib/array/Array<i32>#__unchecked_set
1048+
(tee_local $0
1049+
(call $~lib/array/Array<i32>#constructor)
1050+
)
1051+
(i32.const 0)
1052+
(call $std/array-literal/RefWithCtor#constructor)
1053+
)
1054+
(call $~lib/array/Array<i32>#__unchecked_set
1055+
(get_local $0)
1056+
(i32.const 1)
1057+
(call $std/array-literal/RefWithCtor#constructor)
1058+
)
1059+
(call $~lib/array/Array<i32>#__unchecked_set
1060+
(get_local $0)
1061+
(i32.const 2)
1062+
(call $std/array-literal/RefWithCtor#constructor)
1063+
)
1064+
(set_global $std/array-literal/dynamicArrayRefWithCtor
1065+
(get_local $0)
1066+
)
1067+
(if
1068+
(i32.ne
1069+
(i32.load offset=4
1070+
(get_global $std/array-literal/dynamicArrayRefWithCtor)
1071+
)
1072+
(i32.const 3)
1073+
)
1074+
(block
1075+
(call $~lib/env/abort
1076+
(i32.const 0)
1077+
(i32.const 32)
1078+
(i32.const 40)
1079+
(i32.const 0)
1080+
)
1081+
(unreachable)
1082+
)
1083+
)
9931084
)
994-
(func $null (; 13 ;) (; has Stack IR ;) (type $v)
1085+
(func $null (; 14 ;) (; has Stack IR ;) (type $v)
9951086
(nop)
9961087
)
9971088
)

tests/compiler/std/array-literal.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,11 @@ assert(dynamicArrayI32.length == 3);
3030
assert(dynamicArrayI32[0] == 0);
3131
assert(dynamicArrayI32[1] == 1);
3232
assert(dynamicArrayI32[2] == 2);
33+
34+
class Ref {}
35+
var dynamicArrayRef: Ref[] = [new Ref(), new Ref(), new Ref()];
36+
assert(dynamicArrayRef.length == 3);
37+
38+
class RefWithCtor { constructor() {} }
39+
var dynamicArrayRefWithCtor: RefWithCtor[] = [new RefWithCtor(), new RefWithCtor(), new RefWithCtor()];
40+
assert(dynamicArrayRefWithCtor.length == 3);

0 commit comments

Comments
 (0)