Make sure temp locals don't collide when allocating literal arrays, fixes #281

Originally part of #288
This commit is contained in:
dcodeIO 2018-10-03 01:32:28 +02:00
parent db0e82fbc3
commit eeb8a8fd6c
10 changed files with 513 additions and 60 deletions

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6484,7 +6484,7 @@ export class Compiler extends DiagnosticEmitter {
}
var nativeArrayType = arrayType.toNativeType();
var currentFunction = this.currentFunction;
var tempLocal = currentFunction.getTempLocal(arrayType, false);
var tempLocal = currentFunction.addLocal(arrayType); // can't reuse a temp (used in compiledValues)
var stmts = new Array<ExpressionRef>(2 + length);
var index = 0;
stmts[index++] = module.createSetLocal(tempLocal.index,
@ -6502,7 +6502,7 @@ export class Compiler extends DiagnosticEmitter {
}
assert(index + 1 == stmts.length);
stmts[index] = module.createGetLocal(tempLocal.index, nativeArrayType);
currentFunction.freeTempLocal(tempLocal);
currentFunction.freeTempLocal(tempLocal); // but can be reused now
this.currentType = arrayType;
return module.createBlock(null, stmts, nativeArrayType);
}

View File

@ -354,6 +354,7 @@ declare class Map<K,V> {
entries(): Iterable<[K, V]>;
keys(): Iterable<K>;
values(): Iterable<V>;
delete(key: K): bool;
[Symbol.iterator](): Iterator<[K,V]>;
}

View File

@ -4,8 +4,8 @@
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32)))
(type $v (func))
(type $FUNCSIG$i (func (result i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
@ -13,6 +13,8 @@
(global $std/array-literal/i (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayI8 (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayI32 (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayRef (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayRefWithCtor (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 8) "\03")
(data (i32.const 17) "\01\02")
@ -206,9 +208,9 @@
)
(get_local $1)
)
(func $~lib/memory/memory.allocate (; 6 ;) (; has Stack IR ;) (type $FUNCSIG$i) (result i32)
(func $~lib/memory/memory.allocate (; 6 ;) (; has Stack IR ;) (type $ii) (param $0 i32) (result i32)
(call $~lib/allocator/arena/__memory_allocate
(i32.const 8)
(get_local $0)
)
)
(func $~lib/internal/memory/memset (; 7 ;) (; has Stack IR ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
@ -526,7 +528,9 @@
)
(i32.store
(tee_local $0
(call $~lib/memory/memory.allocate)
(call $~lib/memory/memory.allocate
(i32.const 8)
)
)
(i32.const 0)
)
@ -572,7 +576,9 @@
)
(i32.store
(tee_local $0
(call $~lib/memory/memory.allocate)
(call $~lib/memory/memory.allocate
(i32.const 8)
)
)
(i32.const 0)
)
@ -611,7 +617,12 @@
(get_local $2)
)
)
(func $start (; 12 ;) (; has Stack IR ;) (type $v)
(func $std/array-literal/RefWithCtor#constructor (; 12 ;) (; has Stack IR ;) (type $FUNCSIG$i) (result i32)
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(func $start (; 13 ;) (; has Stack IR ;) (type $v)
(local $0 i32)
(set_global $~lib/allocator/arena/startOffset
(i32.const 232)
@ -990,8 +1001,88 @@
(unreachable)
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(tee_local $0
(call $~lib/array/Array<i32>#constructor)
)
(i32.const 0)
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(i32.const 1)
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(i32.const 2)
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(set_global $std/array-literal/dynamicArrayRef
(get_local $0)
)
(if
(i32.ne
(i32.load offset=4
(get_global $std/array-literal/dynamicArrayRef)
)
(i32.const 3)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 32)
(i32.const 36)
(i32.const 0)
)
(unreachable)
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(tee_local $0
(call $~lib/array/Array<i32>#constructor)
)
(i32.const 0)
(call $std/array-literal/RefWithCtor#constructor)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(i32.const 1)
(call $std/array-literal/RefWithCtor#constructor)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(i32.const 2)
(call $std/array-literal/RefWithCtor#constructor)
)
(set_global $std/array-literal/dynamicArrayRefWithCtor
(get_local $0)
)
(if
(i32.ne
(i32.load offset=4
(get_global $std/array-literal/dynamicArrayRefWithCtor)
)
(i32.const 3)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 32)
(i32.const 40)
(i32.const 0)
)
(unreachable)
)
)
)
(func $null (; 13 ;) (; has Stack IR ;) (type $v)
(func $null (; 14 ;) (; has Stack IR ;) (type $v)
(nop)
)
)

View File

@ -30,3 +30,11 @@ assert(dynamicArrayI32.length == 3);
assert(dynamicArrayI32[0] == 0);
assert(dynamicArrayI32[1] == 1);
assert(dynamicArrayI32[2] == 2);
class Ref {}
var dynamicArrayRef: Ref[] = [new Ref(), new Ref(), new Ref()];
assert(dynamicArrayRef.length == 3);
class RefWithCtor { constructor() {} }
var dynamicArrayRefWithCtor: RefWithCtor[] = [new RefWithCtor(), new RefWithCtor(), new RefWithCtor()];
assert(dynamicArrayRefWithCtor.length == 3);

View File

@ -19,6 +19,8 @@
(global $~lib/internal/arraybuffer/MAX_BLENGTH i32 (i32.const 1073741816))
(global $std/array-literal/dynamicArrayI8 (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayI32 (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayRef (mut i32) (i32.const 0))
(global $std/array-literal/dynamicArrayRefWithCtor (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 228))
(table 1 1 anyfunc)
(elem (i32.const 0) $null)
@ -823,8 +825,231 @@
)
)
)
(func $start (; 12 ;) (type $v)
(func $~lib/array/Array<Ref>#constructor (; 12 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(if
(i32.gt_u
(get_local $1)
(i32.const 268435454)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 136)
(i32.const 37)
(i32.const 39)
)
(unreachable)
)
)
(set_local $2
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(set_local $3
(call $~lib/internal/arraybuffer/allocateUnsafe
(get_local $2)
)
)
(i32.store
(tee_local $0
(if (result i32)
(get_local $0)
(get_local $0)
(tee_local $0
(block (result i32)
(set_local $4
(call $~lib/memory/memory.allocate
(i32.const 8)
)
)
(i32.store
(get_local $4)
(i32.const 0)
)
(i32.store offset=4
(get_local $4)
(i32.const 0)
)
(get_local $4)
)
)
)
)
(get_local $3)
)
(i32.store offset=4
(get_local $0)
(get_local $1)
)
(block $~lib/memory/memory.fill|inlined.2
(set_local $4
(i32.add
(get_local $3)
(get_global $~lib/internal/arraybuffer/HEADER_SIZE)
)
)
(set_local $5
(i32.const 0)
)
(call $~lib/internal/memory/memset
(get_local $4)
(get_local $5)
(get_local $2)
)
)
(get_local $0)
)
(func $~lib/array/Array<Ref>#__unchecked_set (; 13 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(block $~lib/internal/arraybuffer/storeUnsafe<Ref,Ref>|inlined.0
(set_local $3
(i32.load
(get_local $0)
)
)
(i32.store offset=8
(i32.add
(get_local $3)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(get_local $2)
)
)
)
(func $std/array-literal/RefWithCtor#constructor (; 14 ;) (type $ii) (param $0 i32) (result i32)
(local $1 i32)
(tee_local $0
(if (result i32)
(get_local $0)
(get_local $0)
(tee_local $0
(block (result i32)
(set_local $1
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(get_local $1)
)
)
)
)
)
(func $~lib/array/Array<RefWithCtor>#constructor (; 15 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(if
(i32.gt_u
(get_local $1)
(i32.const 268435454)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 136)
(i32.const 37)
(i32.const 39)
)
(unreachable)
)
)
(set_local $2
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(set_local $3
(call $~lib/internal/arraybuffer/allocateUnsafe
(get_local $2)
)
)
(i32.store
(tee_local $0
(if (result i32)
(get_local $0)
(get_local $0)
(tee_local $0
(block (result i32)
(set_local $4
(call $~lib/memory/memory.allocate
(i32.const 8)
)
)
(i32.store
(get_local $4)
(i32.const 0)
)
(i32.store offset=4
(get_local $4)
(i32.const 0)
)
(get_local $4)
)
)
)
)
(get_local $3)
)
(i32.store offset=4
(get_local $0)
(get_local $1)
)
(block $~lib/memory/memory.fill|inlined.3
(set_local $4
(i32.add
(get_local $3)
(get_global $~lib/internal/arraybuffer/HEADER_SIZE)
)
)
(set_local $5
(i32.const 0)
)
(call $~lib/internal/memory/memset
(get_local $4)
(get_local $5)
(get_local $2)
)
)
(get_local $0)
)
(func $~lib/array/Array<RefWithCtor>#__unchecked_set (; 16 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(block $~lib/internal/arraybuffer/storeUnsafe<RefWithCtor,RefWithCtor>|inlined.0
(set_local $3
(i32.load
(get_local $0)
)
)
(i32.store offset=8
(i32.add
(get_local $3)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(get_local $2)
)
)
)
(func $start (; 17 ;) (type $v)
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -1052,19 +1277,19 @@
)
(set_global $std/array-literal/dynamicArrayI8
(block (result i32)
(set_local $0
(set_local $1
(call $~lib/array/Array<i8>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/array/Array<i8>#__unchecked_set
(get_local $0)
(get_local $1)
(i32.const 0)
(get_global $std/array-literal/i)
)
(call $~lib/array/Array<i8>#__unchecked_set
(get_local $0)
(get_local $1)
(i32.const 1)
(block (result i32)
(set_global $std/array-literal/i
@ -1077,7 +1302,7 @@
)
)
(call $~lib/array/Array<i8>#__unchecked_set
(get_local $0)
(get_local $1)
(i32.const 2)
(block (result i32)
(set_global $std/array-literal/i
@ -1089,18 +1314,18 @@
(get_global $std/array-literal/i)
)
)
(get_local $0)
(get_local $1)
)
)
(if
(i32.eqz
(i32.eq
(block $~lib/array/Array<i8>#get:length|inlined.1 (result i32)
(set_local $0
(set_local $1
(get_global $std/array-literal/dynamicArrayI8)
)
(i32.load offset=4
(get_local $0)
(get_local $1)
)
)
(i32.const 3)
@ -1199,19 +1424,19 @@
)
(set_global $std/array-literal/dynamicArrayI32
(block (result i32)
(set_local $0
(set_local $2
(call $~lib/array/Array<i32>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(get_local $2)
(i32.const 0)
(get_global $std/array-literal/i)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(get_local $2)
(i32.const 1)
(block (result i32)
(set_global $std/array-literal/i
@ -1224,7 +1449,7 @@
)
)
(call $~lib/array/Array<i32>#__unchecked_set
(get_local $0)
(get_local $2)
(i32.const 2)
(block (result i32)
(set_global $std/array-literal/i
@ -1236,18 +1461,18 @@
(get_global $std/array-literal/i)
)
)
(get_local $0)
(get_local $2)
)
)
(if
(i32.eqz
(i32.eq
(block $~lib/array/Array<i32>#get:length|inlined.2 (result i32)
(set_local $0
(set_local $2
(get_global $std/array-literal/dynamicArrayI32)
)
(i32.load offset=4
(get_local $0)
(get_local $2)
)
)
(i32.const 3)
@ -1323,7 +1548,134 @@
(unreachable)
)
)
(set_global $std/array-literal/dynamicArrayRef
(block (result i32)
(set_local $3
(call $~lib/array/Array<Ref>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $3)
(i32.const 0)
(block (result i32)
(set_local $2
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(get_local $2)
)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $3)
(i32.const 1)
(block (result i32)
(set_local $2
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(get_local $2)
)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $3)
(i32.const 2)
(block (result i32)
(set_local $2
(call $~lib/memory/memory.allocate
(i32.const 0)
)
)
(get_local $2)
)
)
(get_local $3)
)
)
(if
(i32.eqz
(i32.eq
(block $~lib/array/Array<Ref>#get:length|inlined.0 (result i32)
(set_local $3
(get_global $std/array-literal/dynamicArrayRef)
)
(i32.load offset=4
(get_local $3)
)
)
(i32.const 3)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 32)
(i32.const 36)
(i32.const 0)
)
(unreachable)
)
)
(set_global $std/array-literal/dynamicArrayRefWithCtor
(block (result i32)
(set_local $4
(call $~lib/array/Array<RefWithCtor>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/array/Array<RefWithCtor>#__unchecked_set
(get_local $4)
(i32.const 0)
(call $std/array-literal/RefWithCtor#constructor
(i32.const 0)
)
)
(call $~lib/array/Array<RefWithCtor>#__unchecked_set
(get_local $4)
(i32.const 1)
(call $std/array-literal/RefWithCtor#constructor
(i32.const 0)
)
)
(call $~lib/array/Array<RefWithCtor>#__unchecked_set
(get_local $4)
(i32.const 2)
(call $std/array-literal/RefWithCtor#constructor
(i32.const 0)
)
)
(get_local $4)
)
)
(if
(i32.eqz
(i32.eq
(block $~lib/array/Array<RefWithCtor>#get:length|inlined.0 (result i32)
(set_local $4
(get_global $std/array-literal/dynamicArrayRefWithCtor)
)
(i32.load offset=4
(get_local $4)
)
)
(i32.const 3)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 32)
(i32.const 40)
(i32.const 0)
)
(unreachable)
)
)
)
(func $null (; 13 ;) (type $v)
(func $null (; 18 ;) (type $v)
)
)

View File

@ -19958,6 +19958,7 @@
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -24278,32 +24279,32 @@
)
(set_global $std/array/refArr
(block (result i32)
(set_local $0
(set_local $3
(call $~lib/array/Array<Ref>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $0)
(get_local $3)
(i32.const 0)
(call $std/array/Ref#constructor
(i32.const 0)
)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $0)
(get_local $3)
(i32.const 1)
(i32.const 0)
)
(call $~lib/array/Array<Ref>#__unchecked_set
(get_local $0)
(get_local $3)
(i32.const 2)
(call $std/array/Ref#constructor
(i32.const 0)
)
)
(get_local $0)
(get_local $3)
)
)
(if
@ -24330,11 +24331,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i32>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/reversed0)
)
(call $~lib/array/Array<i32>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24355,11 +24356,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i32>#toString|inlined.3 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/reversed1)
)
(call $~lib/array/Array<i32>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24380,11 +24381,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i32>#toString|inlined.5 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/reversed2)
)
(call $~lib/array/Array<i32>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24405,11 +24406,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i32>#toString|inlined.7 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/reversed4)
)
(call $~lib/array/Array<i32>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24430,11 +24431,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i8>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(i32.const 4624)
)
(call $~lib/array/Array<i8>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24455,11 +24456,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<u16>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(i32.const 4688)
)
(call $~lib/array/Array<u16>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24480,11 +24481,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<u64>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(i32.const 5312)
)
(call $~lib/array/Array<u64>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24505,11 +24506,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<i64>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(i32.const 5512)
)
(call $~lib/array/Array<i64>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24530,11 +24531,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<String>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/randomStringsExpected)
)
(call $~lib/array/Array<String>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24555,11 +24556,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<String>#toString|inlined.3 (result i32)
(set_local $0
(set_local $3
(i32.const 5728)
)
(call $~lib/array/Array<String>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24580,11 +24581,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<Array<i32>>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/subarr32)
)
(call $~lib/array/Array<Array<i32>>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24605,11 +24606,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<Array<u8>>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/subarr8)
)
(call $~lib/array/Array<Array<u8>>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)
@ -24630,11 +24631,11 @@
(i32.eqz
(call $~lib/string/String.__eq
(block $~lib/array/Array<Array<Array<u32>>>#toString|inlined.1 (result i32)
(set_local $0
(set_local $3
(get_global $std/array/subarrU32)
)
(call $~lib/array/Array<Array<Array<u32>>>#join
(get_local $0)
(get_local $3)
(i32.const 1776)
)
)