From 1fe2472691a11c456283b9f5d745b5f0e2479f56 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 26 Mar 2020 02:20:13 +0100 Subject: [PATCH 1/2] Handle instantiation of unmanaged class via object literal --- src/compiler.ts | 33 +- .../std/object-literal-unmanaged.json | 5 + .../object-literal-unmanaged.optimized.wat | 909 +++++++++++ .../compiler/std/object-literal-unmanaged.ts | 11 + .../object-literal-unmanaged.untouched.wat | 1429 +++++++++++++++++ 5 files changed, 2378 insertions(+), 9 deletions(-) create mode 100644 tests/compiler/std/object-literal-unmanaged.json create mode 100644 tests/compiler/std/object-literal-unmanaged.optimized.wat create mode 100644 tests/compiler/std/object-literal-unmanaged.ts create mode 100644 tests/compiler/std/object-literal-unmanaged.untouched.wat diff --git a/src/compiler.ts b/src/compiler.ts index 495f670822..fee405b2f5 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -6628,13 +6628,20 @@ export class Compiler extends DiagnosticEmitter { } /** Checks that an unsafe expression is allowed. */ - private checkUnsafe(reportNode: Node): void { + private checkUnsafe(reportNode: Node, relatedReportNode: Node | null = null): void { // Library files may always use unsafe features if (this.options.noUnsafe && !reportNode.range.source.isLibrary) { - this.error( - DiagnosticCode.Operation_is_unsafe, - reportNode.range - ); + if (relatedReportNode) { + this.errorRelated( + DiagnosticCode.Operation_is_unsafe, + reportNode.range, relatedReportNode.range + ); + } else { + this.error( + DiagnosticCode.Operation_is_unsafe, + reportNode.range + ); + } } } @@ -8640,6 +8647,11 @@ export class Compiler extends DiagnosticEmitter { if (ctor.hasDecorator(DecoratorFlags.UNSAFE)) this.checkUnsafe(expression); } + var isManaged = classReference.type.isManaged; + if (!isManaged) { + this.checkUnsafe(expression, findDecorator(DecoratorKind.UNMANAGED, classReference.decoratorNodes)); + } + // check and compile field values var names = expression.names; var numNames = names.length; @@ -8648,7 +8660,9 @@ export class Compiler extends DiagnosticEmitter { var hasErrors = false; var exprs = new Array(numNames + 2); var flow = this.currentFlow; - var tempLocal = flow.getAutoreleaseLocal(classReference.type); + var tempLocal = isManaged + ? flow.getAutoreleaseLocal(classReference.type) + : flow.getTempLocal(classReference.type); assert(numNames == values.length); for (let i = 0, k = numNames; i < k; ++i) { let member = members ? members.get(names[i].text) : null; @@ -8676,14 +8690,15 @@ export class Compiler extends DiagnosticEmitter { // allocate a new instance first and assign 'this' to the temp. local exprs[0] = module.local_set( tempLocal.index, - this.makeRetain( - this.makeAllocation(classReference) - ) + isManaged + ? this.makeRetain(this.makeAllocation(classReference)) + : this.makeAllocation(classReference) ); // once all field values have been set, return 'this' exprs[exprs.length - 1] = module.local_get(tempLocal.index, this.options.nativeSizeType); + if (!isManaged) flow.freeTempLocal(tempLocal); this.currentType = classReference.type; return module.flatten(exprs, this.options.nativeSizeType); } diff --git a/tests/compiler/std/object-literal-unmanaged.json b/tests/compiler/std/object-literal-unmanaged.json new file mode 100644 index 0000000000..11b43d4296 --- /dev/null +++ b/tests/compiler/std/object-literal-unmanaged.json @@ -0,0 +1,5 @@ +{ + "asc_flags": [ + "--runtime half" + ] +} \ No newline at end of file diff --git a/tests/compiler/std/object-literal-unmanaged.optimized.wat b/tests/compiler/std/object-literal-unmanaged.optimized.wat new file mode 100644 index 0000000000..bf763905df --- /dev/null +++ b/tests/compiler/std/object-literal-unmanaged.optimized.wat @@ -0,0 +1,909 @@ +(module + (type $i32_i32_=>_none (func (param i32 i32))) + (type $i32_=>_i32 (func (param i32) (result i32))) + (type $none_=>_none (func)) + (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) + (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) + (type $none_=>_i32 (func (result i32))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (memory $0 1) + (data (i32.const 1024) "\1e\00\00\00\01\00\00\00\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") + (data (i32.const 1072) "(\00\00\00\01\00\00\00\01\00\00\00(\00\00\00a\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") + (data (i32.const 1136) ">\00\00\00\01\00\00\00\01\00\00\00>\00\00\00s\00t\00d\00/\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00-\00u\00n\00m\00a\00n\00a\00g\00e\00d\00.\00t\00s") + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/rt/tlsf/collectLock (mut i32) (i32.const 0)) + (export "memory" (memory $0)) + (start $~start) + (func $~lib/rt/tlsf/removeBlock (; 1 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $1 + i32.load + local.tee $2 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 277 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $2 + i32.const -4 + i32.and + local.tee $2 + i32.const 16 + i32.ge_u + if (result i32) + local.get $2 + i32.const 1073741808 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 279 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $2 + i32.const 256 + i32.lt_u + if + local.get $2 + i32.const 4 + i32.shr_u + local.set $2 + else + local.get $2 + i32.const 31 + local.get $2 + i32.clz + i32.sub + local.tee $4 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + local.set $2 + local.get $4 + i32.const 7 + i32.sub + local.set $4 + end + local.get $2 + i32.const 16 + i32.lt_u + i32.const 0 + local.get $4 + i32.const 23 + i32.lt_u + select + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 292 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load offset=20 + local.set $3 + local.get $1 + i32.load offset=16 + local.tee $5 + if + local.get $5 + local.get $3 + i32.store offset=20 + end + local.get $3 + if + local.get $3 + local.get $5 + i32.store offset=16 + end + local.get $1 + local.get $0 + local.get $2 + local.get $4 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + i32.eq + if + local.get $0 + local.get $2 + local.get $4 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + local.get $3 + i32.store offset=96 + local.get $3 + i32.eqz + if + local.get $0 + local.get $4 + i32.const 2 + i32.shl + i32.add + local.tee $3 + i32.load offset=4 + i32.const 1 + local.get $2 + i32.shl + i32.const -1 + i32.xor + i32.and + local.set $1 + local.get $3 + local.get $1 + i32.store offset=4 + local.get $1 + i32.eqz + if + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $4 + i32.shl + i32.const -1 + i32.xor + i32.and + i32.store + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (; 2 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + local.get $1 + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 205 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load + local.tee $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 207 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 16 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.tee $5 + i32.const 1 + i32.and + if + local.get $3 + i32.const -4 + i32.and + i32.const 16 + i32.add + local.get $5 + i32.const -4 + i32.and + i32.add + local.tee $2 + i32.const 1073741808 + i32.lt_u + if + local.get $0 + local.get $4 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $2 + local.get $3 + i32.const 3 + i32.and + i32.or + local.tee $3 + i32.store + local.get $1 + i32.const 16 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $4 + i32.load + local.set $5 + end + end + local.get $3 + i32.const 2 + i32.and + if + local.get $1 + i32.const 4 + i32.sub + i32.load + local.tee $2 + i32.load + local.tee $7 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 228 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $7 + i32.const -4 + i32.and + i32.const 16 + i32.add + local.get $3 + i32.const -4 + i32.and + i32.add + local.tee $8 + i32.const 1073741808 + i32.lt_u + if + local.get $0 + local.get $2 + call $~lib/rt/tlsf/removeBlock + local.get $2 + local.get $8 + local.get $7 + i32.const 3 + i32.and + i32.or + local.tee $3 + i32.store + local.get $2 + local.set $1 + end + end + local.get $4 + local.get $5 + i32.const 2 + i32.or + i32.store + local.get $3 + i32.const -4 + i32.and + local.tee $2 + i32.const 16 + i32.ge_u + if (result i32) + local.get $2 + i32.const 1073741808 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 243 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $2 + local.get $1 + i32.const 16 + i32.add + i32.add + local.get $4 + i32.ne + if + i32.const 0 + i32.const 1040 + i32.const 244 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 4 + i32.sub + local.get $1 + i32.store + local.get $2 + i32.const 256 + i32.lt_u + if + local.get $2 + i32.const 4 + i32.shr_u + local.set $2 + else + local.get $2 + i32.const 31 + local.get $2 + i32.clz + i32.sub + local.tee $3 + i32.const 4 + i32.sub + i32.shr_u + i32.const 16 + i32.xor + local.set $2 + local.get $3 + i32.const 7 + i32.sub + local.set $6 + end + local.get $2 + i32.const 16 + i32.lt_u + i32.const 0 + local.get $6 + i32.const 23 + i32.lt_u + select + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 260 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $2 + local.get $6 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $3 + local.get $1 + i32.const 0 + i32.store offset=16 + local.get $1 + local.get $3 + i32.store offset=20 + local.get $3 + if + local.get $3 + local.get $1 + i32.store offset=16 + end + local.get $0 + local.get $2 + local.get $6 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + local.get $1 + i32.store offset=96 + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $6 + i32.shl + i32.or + i32.store + local.get $0 + local.get $6 + i32.const 2 + i32.shl + i32.add + local.tee $0 + local.get $0 + i32.load offset=4 + i32.const 1 + local.get $2 + i32.shl + i32.or + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (; 3 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + local.get $2 + i32.const 15 + i32.and + i32.eqz + i32.const 0 + local.get $1 + i32.const 15 + i32.and + i32.eqz + i32.const 0 + local.get $1 + local.get $2 + i32.le_u + select + select + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 386 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.load offset=1568 + local.tee $3 + if + local.get $1 + local.get $3 + i32.const 16 + i32.add + i32.lt_u + if + i32.const 0 + i32.const 1040 + i32.const 396 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $3 + local.get $1 + i32.const 16 + i32.sub + i32.eq + if + local.get $3 + i32.load + local.set $4 + local.get $1 + i32.const 16 + i32.sub + local.set $1 + end + else + local.get $1 + local.get $0 + i32.const 1572 + i32.add + i32.lt_u + if + i32.const 0 + i32.const 1040 + i32.const 408 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $2 + local.get $1 + i32.sub + local.tee $2 + i32.const 48 + i32.lt_u + if + return + end + local.get $1 + local.get $4 + i32.const 2 + i32.and + local.get $2 + i32.const 32 + i32.sub + i32.const 1 + i32.or + i32.or + i32.store + local.get $1 + i32.const 0 + i32.store offset=16 + local.get $1 + i32.const 0 + i32.store offset=20 + local.get $1 + local.get $2 + i32.add + i32.const 16 + i32.sub + local.tee $2 + i32.const 2 + i32.store + local.get $0 + local.get $2 + i32.store offset=1568 + local.get $0 + local.get $1 + call $~lib/rt/tlsf/insertBlock + ) + (func $~lib/rt/tlsf/maybeInitialize (; 4 ;) (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + global.get $~lib/rt/tlsf/ROOT + local.tee $0 + i32.eqz + if + i32.const 1 + memory.size + local.tee $0 + i32.gt_s + if (result i32) + i32.const 1 + local.get $0 + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + i32.const 1216 + local.tee $0 + i32.const 0 + i32.store + i32.const 2784 + i32.const 0 + i32.store + loop $for-loop|0 + local.get $1 + i32.const 23 + i32.lt_u + if + local.get $1 + i32.const 2 + i32.shl + i32.const 1216 + i32.add + i32.const 0 + i32.store offset=4 + i32.const 0 + local.set $2 + loop $for-loop|1 + local.get $2 + i32.const 16 + i32.lt_u + if + local.get $2 + local.get $1 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.const 1216 + i32.add + i32.const 0 + i32.store offset=96 + local.get $2 + i32.const 1 + i32.add + local.set $2 + br $for-loop|1 + end + end + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $for-loop|0 + end + end + i32.const 1216 + i32.const 2800 + memory.size + i32.const 16 + i32.shl + call $~lib/rt/tlsf/addMemory + i32.const 1216 + global.set $~lib/rt/tlsf/ROOT + end + local.get $0 + ) + (func $~lib/rt/tlsf/searchBlock (; 5 ;) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + nop + local.get $0 + i32.load offset=4 + i32.const -2 + i32.and + local.tee $2 + if (result i32) + local.get $0 + local.get $2 + i32.ctz + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + local.get $0 + i32.load + i32.const -2 + i32.and + local.tee $1 + if (result i32) + local.get $0 + local.get $1 + i32.ctz + local.tee $1 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.tee $2 + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 351 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $2 + i32.ctz + local.get $1 + i32.const 4 + i32.shl + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + else + i32.const 0 + end + end + ) + (func $~lib/rt/tlsf/allocateBlock (; 6 ;) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + global.get $~lib/rt/tlsf/collectLock + if + i32.const 0 + i32.const 1040 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + call $~lib/rt/tlsf/searchBlock + local.tee $1 + i32.eqz + if + i32.const 1 + global.set $~lib/rt/tlsf/collectLock + i32.const 0 + global.set $~lib/rt/tlsf/collectLock + local.get $0 + call $~lib/rt/tlsf/searchBlock + local.tee $1 + i32.eqz + if + i32.const 16 + memory.size + local.tee $2 + i32.const 16 + i32.shl + i32.const 16 + i32.sub + local.get $0 + i32.load offset=1568 + i32.ne + i32.shl + i32.const 65551 + i32.add + i32.const -65536 + i32.and + i32.const 16 + i32.shr_u + local.set $1 + local.get $2 + local.get $1 + local.get $2 + local.get $1 + i32.gt_s + select + memory.grow + i32.const 0 + i32.lt_s + if + local.get $1 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + local.get $0 + local.get $2 + i32.const 16 + i32.shl + memory.size + i32.const 16 + i32.shl + call $~lib/rt/tlsf/addMemory + local.get $0 + call $~lib/rt/tlsf/searchBlock + local.tee $1 + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 513 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + end + end + local.get $1 + i32.load + i32.const -4 + i32.and + i32.const 16 + i32.lt_u + if + i32.const 0 + i32.const 1040 + i32.const 521 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 0 + i32.store offset=4 + local.get $1 + i32.const 0 + i32.store offset=8 + local.get $1 + i32.const 4 + i32.store offset=12 + local.get $0 + local.get $1 + call $~lib/rt/tlsf/removeBlock + local.get $1 + i32.load + local.tee $2 + i32.const -4 + i32.and + i32.const 16 + i32.sub + local.tee $3 + i32.const 32 + i32.ge_u + if + local.get $1 + local.get $2 + i32.const 2 + i32.and + i32.const 16 + i32.or + i32.store + local.get $1 + i32.const 32 + i32.add + local.tee $2 + local.get $3 + i32.const 16 + i32.sub + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $2 + call $~lib/rt/tlsf/insertBlock + else + local.get $1 + local.get $2 + i32.const -2 + i32.and + i32.store + local.get $1 + i32.const 16 + i32.add + local.tee $0 + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.get $0 + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + i32.load + i32.const -3 + i32.and + i32.store + end + local.get $1 + ) + (func $~start (; 7 ;) + (local $0 i32) + call $~lib/rt/tlsf/maybeInitialize + call $~lib/rt/tlsf/allocateBlock + i32.const 16 + i32.add + local.tee $0 + i32.const 123 + i32.store + local.get $0 + i32.load + i32.const 123 + i32.ne + if + i32.const 0 + i32.const 1152 + i32.const 11 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) +) diff --git a/tests/compiler/std/object-literal-unmanaged.ts b/tests/compiler/std/object-literal-unmanaged.ts new file mode 100644 index 0000000000..80b6452e88 --- /dev/null +++ b/tests/compiler/std/object-literal-unmanaged.ts @@ -0,0 +1,11 @@ +@unmanaged +class Foo { + a: i32; +} + +function test(a: i32): i32 { + var foo: Foo = { a: a }; + return foo.a; +} + +assert(test(123) == 123); diff --git a/tests/compiler/std/object-literal-unmanaged.untouched.wat b/tests/compiler/std/object-literal-unmanaged.untouched.wat new file mode 100644 index 0000000000..d44d7b6d42 --- /dev/null +++ b/tests/compiler/std/object-literal-unmanaged.untouched.wat @@ -0,0 +1,1429 @@ +(module + (type $none_=>_none (func)) + (type $i32_i32_=>_none (func (param i32 i32))) + (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) + (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) + (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) + (type $none_=>_i32 (func (result i32))) + (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (memory $0 1) + (data (i32.const 16) "\1e\00\00\00\01\00\00\00\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00") + (data (i32.const 64) "(\00\00\00\01\00\00\00\01\00\00\00(\00\00\00a\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00") + (data (i32.const 128) ">\00\00\00\01\00\00\00\01\00\00\00>\00\00\00s\00t\00d\00/\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00-\00u\00n\00m\00a\00n\00a\00g\00e\00d\00.\00t\00s\00") + (table $0 1 funcref) + (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) + (global $~lib/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) + (global $~lib/rt/tlsf/collectLock (mut i32) (i32.const 0)) + (global $~lib/gc/gc.auto (mut i32) (i32.const 1)) + (global $~lib/heap/__heap_base i32 (i32.const 208)) + (export "memory" (memory $0)) + (start $~start) + (func $~lib/rt/tlsf/removeBlock (; 1 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + local.get $1 + i32.load + local.set $2 + local.get $2 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 277 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $2 + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $3 + local.get $3 + i32.const 16 + i32.ge_u + if (result i32) + local.get $3 + i32.const 1073741808 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 279 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $4 + local.get $3 + i32.const 4 + i32.shr_u + local.set $5 + else + i32.const 31 + local.get $3 + i32.clz + i32.sub + local.set $4 + local.get $3 + local.get $4 + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $5 + local.get $4 + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $4 + end + local.get $4 + i32.const 23 + i32.lt_u + if (result i32) + local.get $5 + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 292 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load offset=16 + local.set $6 + local.get $1 + i32.load offset=20 + local.set $7 + local.get $6 + if + local.get $6 + local.get $7 + i32.store offset=20 + end + local.get $7 + if + local.get $7 + local.get $6 + i32.store offset=16 + end + local.get $1 + local.get $0 + local.set $10 + local.get $4 + local.set $9 + local.get $5 + local.set $8 + local.get $10 + local.get $9 + i32.const 4 + i32.shl + local.get $8 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + i32.eq + if + local.get $0 + local.set $11 + local.get $4 + local.set $10 + local.get $5 + local.set $9 + local.get $7 + local.set $8 + local.get $11 + local.get $10 + i32.const 4 + i32.shl + local.get $9 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $8 + i32.store offset=96 + local.get $7 + i32.eqz + if + local.get $0 + local.set $9 + local.get $4 + local.set $8 + local.get $9 + local.get $8 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.set $9 + local.get $0 + local.set $8 + local.get $4 + local.set $11 + local.get $9 + i32.const 1 + local.get $5 + i32.shl + i32.const -1 + i32.xor + i32.and + local.tee $9 + local.set $10 + local.get $8 + local.get $11 + i32.const 2 + i32.shl + i32.add + local.get $10 + i32.store offset=4 + local.get $9 + i32.eqz + if + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $4 + i32.shl + i32.const -1 + i32.xor + i32.and + i32.store + end + end + end + ) + (func $~lib/rt/tlsf/insertBlock (; 2 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + local.get $1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 205 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.load + local.set $2 + local.get $2 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 207 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + local.set $3 + local.get $3 + i32.const 16 + i32.add + local.get $3 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.set $4 + local.get $4 + i32.load + local.set $5 + local.get $5 + i32.const 1 + i32.and + if + local.get $2 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.add + local.get $5 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.set $3 + local.get $3 + i32.const 1073741808 + i32.lt_u + if + local.get $0 + local.get $4 + call $~lib/rt/tlsf/removeBlock + local.get $1 + local.get $2 + i32.const 3 + i32.and + local.get $3 + i32.or + local.tee $2 + i32.store + local.get $1 + local.set $6 + local.get $6 + i32.const 16 + i32.add + local.get $6 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.set $4 + local.get $4 + i32.load + local.set $5 + end + end + local.get $2 + i32.const 2 + i32.and + if + local.get $1 + local.set $6 + local.get $6 + i32.const 4 + i32.sub + i32.load + local.set $6 + local.get $6 + i32.load + local.set $3 + local.get $3 + i32.const 1 + i32.and + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 228 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.add + local.get $2 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.set $7 + local.get $7 + i32.const 1073741808 + i32.lt_u + if + local.get $0 + local.get $6 + call $~lib/rt/tlsf/removeBlock + local.get $6 + local.get $3 + i32.const 3 + i32.and + local.get $7 + i32.or + local.tee $2 + i32.store + local.get $6 + local.set $1 + end + end + local.get $4 + local.get $5 + i32.const 2 + i32.or + i32.store + local.get $2 + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.set $8 + local.get $8 + i32.const 16 + i32.ge_u + if (result i32) + local.get $8 + i32.const 1073741808 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 243 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 16 + i32.add + local.get $8 + i32.add + local.get $4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 244 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 4 + i32.sub + local.get $1 + i32.store + local.get $8 + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $9 + local.get $8 + i32.const 4 + i32.shr_u + local.set $10 + else + i32.const 31 + local.get $8 + i32.clz + i32.sub + local.set $9 + local.get $8 + local.get $9 + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $10 + local.get $9 + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $9 + end + local.get $9 + i32.const 23 + i32.lt_u + if (result i32) + local.get $10 + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 260 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.set $7 + local.get $9 + local.set $3 + local.get $10 + local.set $6 + local.get $7 + local.get $3 + i32.const 4 + i32.shl + local.get $6 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $11 + local.get $1 + i32.const 0 + i32.store offset=16 + local.get $1 + local.get $11 + i32.store offset=20 + local.get $11 + if + local.get $11 + local.get $1 + i32.store offset=16 + end + local.get $0 + local.set $12 + local.get $9 + local.set $7 + local.get $10 + local.set $3 + local.get $1 + local.set $6 + local.get $12 + local.get $7 + i32.const 4 + i32.shl + local.get $3 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $6 + i32.store offset=96 + local.get $0 + local.get $0 + i32.load + i32.const 1 + local.get $9 + i32.shl + i32.or + i32.store + local.get $0 + local.set $13 + local.get $9 + local.set $12 + local.get $0 + local.set $3 + local.get $9 + local.set $6 + local.get $3 + local.get $6 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + i32.const 1 + local.get $10 + i32.shl + i32.or + local.set $7 + local.get $13 + local.get $12 + i32.const 2 + i32.shl + i32.add + local.get $7 + i32.store offset=4 + ) + (func $~lib/rt/tlsf/addMemory (; 3 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + local.get $1 + local.get $2 + i32.le_u + if (result i32) + local.get $1 + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $2 + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 386 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.set $3 + local.get $3 + i32.load offset=1568 + local.set $4 + i32.const 0 + local.set $5 + local.get $4 + if + local.get $1 + local.get $4 + i32.const 16 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 396 + i32.const 16 + call $~lib/builtins/abort + unreachable + end + local.get $1 + i32.const 16 + i32.sub + local.get $4 + i32.eq + if + local.get $1 + i32.const 16 + i32.sub + local.set $1 + local.get $4 + i32.load + local.set $5 + else + nop + end + else + local.get $1 + local.get $0 + i32.const 1572 + i32.add + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 408 + i32.const 5 + call $~lib/builtins/abort + unreachable + end + end + local.get $2 + local.get $1 + i32.sub + local.set $6 + local.get $6 + i32.const 48 + i32.lt_u + if + i32.const 0 + return + end + local.get $6 + i32.const 16 + i32.const 1 + i32.shl + i32.sub + local.set $7 + local.get $1 + local.set $8 + local.get $8 + local.get $7 + i32.const 1 + i32.or + local.get $5 + i32.const 2 + i32.and + i32.or + i32.store + local.get $8 + i32.const 0 + i32.store offset=16 + local.get $8 + i32.const 0 + i32.store offset=20 + local.get $1 + local.get $6 + i32.add + i32.const 16 + i32.sub + local.set $4 + local.get $4 + i32.const 0 + i32.const 2 + i32.or + i32.store + local.get $0 + local.set $9 + local.get $4 + local.set $3 + local.get $9 + local.get $3 + i32.store offset=1568 + local.get $0 + local.get $8 + call $~lib/rt/tlsf/insertBlock + i32.const 1 + ) + (func $~lib/rt/tlsf/maybeInitialize (; 4 ;) (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + global.get $~lib/rt/tlsf/ROOT + local.set $0 + local.get $0 + i32.eqz + if + global.get $~lib/heap/__heap_base + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $1 + memory.size + local.set $2 + local.get $1 + i32.const 1572 + i32.add + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $3 + local.get $3 + local.get $2 + i32.gt_s + if (result i32) + local.get $3 + local.get $2 + i32.sub + memory.grow + i32.const 0 + i32.lt_s + else + i32.const 0 + end + if + unreachable + end + local.get $1 + local.set $0 + local.get $0 + i32.const 0 + i32.store + local.get $0 + local.set $5 + i32.const 0 + local.set $4 + local.get $5 + local.get $4 + i32.store offset=1568 + i32.const 0 + local.set $5 + loop $for-loop|0 + local.get $5 + i32.const 23 + i32.lt_u + local.set $4 + local.get $4 + if + local.get $0 + local.set $8 + local.get $5 + local.set $7 + i32.const 0 + local.set $6 + local.get $8 + local.get $7 + i32.const 2 + i32.shl + i32.add + local.get $6 + i32.store offset=4 + i32.const 0 + local.set $8 + loop $for-loop|1 + local.get $8 + i32.const 16 + i32.lt_u + local.set $7 + local.get $7 + if + local.get $0 + local.set $11 + local.get $5 + local.set $10 + local.get $8 + local.set $9 + i32.const 0 + local.set $6 + local.get $11 + local.get $10 + i32.const 4 + i32.shl + local.get $9 + i32.add + i32.const 2 + i32.shl + i32.add + local.get $6 + i32.store offset=96 + local.get $8 + i32.const 1 + i32.add + local.set $8 + br $for-loop|1 + end + end + local.get $5 + i32.const 1 + i32.add + local.set $5 + br $for-loop|0 + end + end + local.get $1 + i32.const 1572 + i32.add + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.set $5 + local.get $0 + local.get $5 + memory.size + i32.const 16 + i32.shl + call $~lib/rt/tlsf/addMemory + drop + local.get $0 + global.set $~lib/rt/tlsf/ROOT + end + local.get $0 + ) + (func $~lib/rt/tlsf/prepareSize (; 5 ;) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + local.get $0 + i32.const 1073741808 + i32.ge_u + if + i32.const 80 + i32.const 32 + i32.const 461 + i32.const 30 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $1 + i32.const 16 + local.tee $2 + local.get $1 + local.get $2 + i32.gt_u + select + ) + (func $~lib/rt/tlsf/searchBlock (; 6 ;) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + local.get $1 + i32.const 256 + i32.lt_u + if + i32.const 0 + local.set $2 + local.get $1 + i32.const 4 + i32.shr_u + local.set $3 + else + local.get $1 + i32.const 536870904 + i32.lt_u + if (result i32) + local.get $1 + i32.const 1 + i32.const 27 + local.get $1 + i32.clz + i32.sub + i32.shl + i32.add + i32.const 1 + i32.sub + else + local.get $1 + end + local.set $4 + i32.const 31 + local.get $4 + i32.clz + i32.sub + local.set $2 + local.get $4 + local.get $2 + i32.const 4 + i32.sub + i32.shr_u + i32.const 1 + i32.const 4 + i32.shl + i32.xor + local.set $3 + local.get $2 + i32.const 8 + i32.const 1 + i32.sub + i32.sub + local.set $2 + end + local.get $2 + i32.const 23 + i32.lt_u + if (result i32) + local.get $3 + i32.const 16 + i32.lt_u + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 338 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.set $5 + local.get $2 + local.set $4 + local.get $5 + local.get $4 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + i32.const 0 + i32.const -1 + i32.xor + local.get $3 + i32.shl + i32.and + local.set $6 + i32.const 0 + local.set $7 + local.get $6 + i32.eqz + if + local.get $0 + i32.load + i32.const 0 + i32.const -1 + i32.xor + local.get $2 + i32.const 1 + i32.add + i32.shl + i32.and + local.set $5 + local.get $5 + i32.eqz + if + i32.const 0 + local.set $7 + else + local.get $5 + i32.ctz + local.set $2 + local.get $0 + local.set $8 + local.get $2 + local.set $4 + local.get $8 + local.get $4 + i32.const 2 + i32.shl + i32.add + i32.load offset=4 + local.set $6 + local.get $6 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 351 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.set $9 + local.get $2 + local.set $8 + local.get $6 + i32.ctz + local.set $4 + local.get $9 + local.get $8 + i32.const 4 + i32.shl + local.get $4 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $7 + end + else + local.get $0 + local.set $9 + local.get $2 + local.set $8 + local.get $6 + i32.ctz + local.set $4 + local.get $9 + local.get $8 + i32.const 4 + i32.shl + local.get $4 + i32.add + i32.const 2 + i32.shl + i32.add + i32.load offset=96 + local.set $7 + end + local.get $7 + ) + (func $~lib/rt/tlsf/growMemory (; 7 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + local.get $1 + i32.const 536870904 + i32.lt_u + if + local.get $1 + i32.const 1 + i32.const 27 + local.get $1 + i32.clz + i32.sub + i32.shl + i32.const 1 + i32.sub + i32.add + local.set $1 + end + memory.size + local.set $2 + local.get $1 + i32.const 16 + local.get $2 + i32.const 16 + i32.shl + i32.const 16 + i32.sub + local.get $0 + local.set $3 + local.get $3 + i32.load offset=1568 + i32.ne + i32.shl + i32.add + local.set $1 + local.get $1 + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $4 + local.get $2 + local.tee $3 + local.get $4 + local.tee $5 + local.get $3 + local.get $5 + i32.gt_s + select + local.set $6 + local.get $6 + memory.grow + i32.const 0 + i32.lt_s + if + local.get $4 + memory.grow + i32.const 0 + i32.lt_s + if + unreachable + end + end + memory.size + local.set $7 + local.get $0 + local.get $2 + i32.const 16 + i32.shl + local.get $7 + i32.const 16 + i32.shl + call $~lib/rt/tlsf/addMemory + drop + ) + (func $~lib/rt/tlsf/prepareBlock (; 8 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + local.get $1 + i32.load + local.set $3 + local.get $2 + i32.const 15 + i32.and + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 365 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $2 + i32.sub + local.set $4 + local.get $4 + i32.const 32 + i32.ge_u + if + local.get $1 + local.get $2 + local.get $3 + i32.const 2 + i32.and + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.get $2 + i32.add + local.set $5 + local.get $5 + local.get $4 + i32.const 16 + i32.sub + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $5 + call $~lib/rt/tlsf/insertBlock + else + local.get $1 + local.get $3 + i32.const 1 + i32.const -1 + i32.xor + i32.and + i32.store + local.get $1 + local.set $5 + local.get $5 + i32.const 16 + i32.add + local.get $5 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.get $1 + local.set $5 + local.get $5 + i32.const 16 + i32.add + local.get $5 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + i32.load + i32.const 2 + i32.const -1 + i32.xor + i32.and + i32.store + end + ) + (func $~lib/rt/tlsf/allocateBlock (; 9 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + global.get $~lib/rt/tlsf/collectLock + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 501 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $1 + call $~lib/rt/tlsf/prepareSize + local.set $3 + local.get $0 + local.get $3 + call $~lib/rt/tlsf/searchBlock + local.set $4 + local.get $4 + i32.eqz + if + global.get $~lib/gc/gc.auto + if + i32.const 1 + global.set $~lib/rt/tlsf/collectLock + call $~lib/rt/pure/__collect + i32.const 0 + global.set $~lib/rt/tlsf/collectLock + local.get $0 + local.get $3 + call $~lib/rt/tlsf/searchBlock + local.set $4 + local.get $4 + i32.eqz + if + local.get $0 + local.get $3 + call $~lib/rt/tlsf/growMemory + local.get $0 + local.get $3 + call $~lib/rt/tlsf/searchBlock + local.set $4 + local.get $4 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 513 + i32.const 20 + call $~lib/builtins/abort + unreachable + end + end + else + local.get $0 + local.get $3 + call $~lib/rt/tlsf/growMemory + local.get $0 + local.get $3 + call $~lib/rt/tlsf/searchBlock + local.set $4 + local.get $4 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 518 + i32.const 18 + call $~lib/builtins/abort + unreachable + end + end + end + local.get $4 + i32.load + i32.const -4 + i32.and + local.get $3 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 521 + i32.const 14 + call $~lib/builtins/abort + unreachable + end + local.get $4 + i32.const 0 + i32.store offset=4 + local.get $4 + local.get $2 + i32.store offset=8 + local.get $4 + local.get $1 + i32.store offset=12 + local.get $0 + local.get $4 + call $~lib/rt/tlsf/removeBlock + local.get $0 + local.get $4 + local.get $3 + call $~lib/rt/tlsf/prepareBlock + local.get $4 + ) + (func $~lib/rt/tlsf/__alloc (; 10 ;) (param $0 i32) (param $1 i32) (result i32) + call $~lib/rt/tlsf/maybeInitialize + local.get $0 + local.get $1 + call $~lib/rt/tlsf/allocateBlock + i32.const 16 + i32.add + ) + (func $std/object-literal-unmanaged/test (; 11 ;) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + i32.const 4 + i32.const 0 + call $~lib/rt/tlsf/__alloc + local.set $1 + local.get $1 + local.get $0 + i32.store + local.get $1 + local.set $2 + local.get $2 + i32.load + ) + (func $start:std/object-literal-unmanaged (; 12 ;) + i32.const 123 + call $std/object-literal-unmanaged/test + i32.const 123 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 144 + i32.const 11 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + ) + (func $~start (; 13 ;) + call $start:std/object-literal-unmanaged + ) + (func $~lib/rt/pure/__collect (; 14 ;) + return + ) +) From 99691ca35507d99d8724dd078cee960c0528e89e Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 26 Mar 2020 02:25:57 +0100 Subject: [PATCH 2/2] validate with rtrace --- .../std/object-literal-unmanaged.json | 3 +- .../object-literal-unmanaged.optimized.wat | 77 ++++++++++-- .../compiler/std/object-literal-unmanaged.ts | 6 +- .../object-literal-unmanaged.untouched.wat | 111 +++++++++++++++--- 4 files changed, 169 insertions(+), 28 deletions(-) diff --git a/tests/compiler/std/object-literal-unmanaged.json b/tests/compiler/std/object-literal-unmanaged.json index 11b43d4296..9f7878d475 100644 --- a/tests/compiler/std/object-literal-unmanaged.json +++ b/tests/compiler/std/object-literal-unmanaged.json @@ -1,5 +1,6 @@ { "asc_flags": [ - "--runtime half" + "--runtime half", + "--use ASC_RTRACE=1" ] } \ No newline at end of file diff --git a/tests/compiler/std/object-literal-unmanaged.optimized.wat b/tests/compiler/std/object-literal-unmanaged.optimized.wat index bf763905df..4bad50a5c3 100644 --- a/tests/compiler/std/object-literal-unmanaged.optimized.wat +++ b/tests/compiler/std/object-literal-unmanaged.optimized.wat @@ -1,4 +1,5 @@ (module + (type $i32_=>_none (func (param i32))) (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $none_=>_none (func)) @@ -6,15 +7,18 @@ (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $none_=>_i32 (func (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (import "rtrace" "onalloc" (func $~lib/rt/rtrace/onalloc (param i32))) + (import "rtrace" "onfree" (func $~lib/rt/rtrace/onfree (param i32))) (memory $0 1) (data (i32.const 1024) "\1e\00\00\00\01\00\00\00\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s") (data (i32.const 1072) "(\00\00\00\01\00\00\00\01\00\00\00(\00\00\00a\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") (data (i32.const 1136) ">\00\00\00\01\00\00\00\01\00\00\00>\00\00\00s\00t\00d\00/\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00-\00u\00n\00m\00a\00n\00a\00g\00e\00d\00.\00t\00s") + (global $std/object-literal-unmanaged/foo (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/collectLock (mut i32) (i32.const 0)) (export "memory" (memory $0)) (start $~start) - (func $~lib/rt/tlsf/removeBlock (; 1 ;) (param $0 i32) (param $1 i32) + (func $~lib/rt/tlsf/removeBlock (; 3 ;) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -176,7 +180,7 @@ end end ) - (func $~lib/rt/tlsf/insertBlock (; 2 ;) (param $0 i32) (param $1 i32) + (func $~lib/rt/tlsf/insertBlock (; 4 ;) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -455,7 +459,7 @@ i32.or i32.store offset=4 ) - (func $~lib/rt/tlsf/addMemory (; 3 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/rt/tlsf/addMemory (; 5 ;) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) local.get $2 @@ -569,7 +573,7 @@ local.get $1 call $~lib/rt/tlsf/insertBlock ) - (func $~lib/rt/tlsf/maybeInitialize (; 4 ;) (result i32) + (func $~lib/rt/tlsf/maybeInitialize (; 6 ;) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) @@ -656,7 +660,7 @@ end local.get $0 ) - (func $~lib/rt/tlsf/searchBlock (; 5 ;) (param $0 i32) (result i32) + (func $~lib/rt/tlsf/searchBlock (; 7 ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) nop @@ -714,7 +718,7 @@ end end ) - (func $~lib/rt/tlsf/allocateBlock (; 6 ;) (param $0 i32) (result i32) + (func $~lib/rt/tlsf/allocateBlock (; 8 ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -883,9 +887,13 @@ i32.store end local.get $1 + call $~lib/rt/rtrace/onalloc + local.get $1 ) - (func $~start (; 7 ;) + (func $~start (; 9 ;) (local $0 i32) + (local $1 i32) + (local $2 i32) call $~lib/rt/tlsf/maybeInitialize call $~lib/rt/tlsf/allocateBlock i32.const 16 @@ -894,16 +902,69 @@ i32.const 123 i32.store local.get $0 + global.set $std/object-literal-unmanaged/foo + global.get $std/object-literal-unmanaged/foo i32.load i32.const 123 i32.ne if i32.const 0 i32.const 1152 - i32.const 11 + i32.const 13 i32.const 1 call $~lib/builtins/abort unreachable end + global.get $std/object-literal-unmanaged/foo + local.set $1 + call $~lib/rt/tlsf/maybeInitialize + local.get $1 + i32.const 16 + i32.sub + local.set $0 + local.get $1 + i32.const 15 + i32.and + i32.eqz + i32.const 0 + local.get $1 + select + if (result i32) + local.get $0 + i32.load + i32.const 1 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $0 + i32.load offset=4 + i32.const -268435456 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 1040 + i32.const 581 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $0 + local.get $0 + i32.load + i32.const 1 + i32.or + i32.store + local.get $0 + call $~lib/rt/tlsf/insertBlock + local.get $0 + call $~lib/rt/rtrace/onfree ) ) diff --git a/tests/compiler/std/object-literal-unmanaged.ts b/tests/compiler/std/object-literal-unmanaged.ts index 80b6452e88..b01dff30c2 100644 --- a/tests/compiler/std/object-literal-unmanaged.ts +++ b/tests/compiler/std/object-literal-unmanaged.ts @@ -3,9 +3,13 @@ class Foo { a: i32; } +var foo: Foo; + function test(a: i32): i32 { - var foo: Foo = { a: a }; + foo = { a: a }; return foo.a; } assert(test(123) == 123); + +__free(changetype(foo)); diff --git a/tests/compiler/std/object-literal-unmanaged.untouched.wat b/tests/compiler/std/object-literal-unmanaged.untouched.wat index d44d7b6d42..3dd6edbab8 100644 --- a/tests/compiler/std/object-literal-unmanaged.untouched.wat +++ b/tests/compiler/std/object-literal-unmanaged.untouched.wat @@ -1,6 +1,7 @@ (module - (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) + (type $none_=>_none (func)) + (type $i32_=>_none (func (param i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) @@ -8,11 +9,14 @@ (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $none_=>_i32 (func (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) + (import "rtrace" "onalloc" (func $~lib/rt/rtrace/onalloc (param i32))) + (import "rtrace" "onfree" (func $~lib/rt/rtrace/onfree (param i32))) (memory $0 1) (data (i32.const 16) "\1e\00\00\00\01\00\00\00\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00") (data (i32.const 64) "(\00\00\00\01\00\00\00\01\00\00\00(\00\00\00a\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00") (data (i32.const 128) ">\00\00\00\01\00\00\00\01\00\00\00>\00\00\00s\00t\00d\00/\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00-\00u\00n\00m\00a\00n\00a\00g\00e\00d\00.\00t\00s\00") (table $0 1 funcref) + (global $std/object-literal-unmanaged/foo (mut i32) (i32.const 0)) (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $~lib/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) (global $~lib/rt/tlsf/collectLock (mut i32) (i32.const 0)) @@ -20,7 +24,7 @@ (global $~lib/heap/__heap_base i32 (i32.const 208)) (export "memory" (memory $0)) (start $~start) - (func $~lib/rt/tlsf/removeBlock (; 1 ;) (param $0 i32) (param $1 i32) + (func $~lib/rt/tlsf/removeBlock (; 3 ;) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -230,7 +234,7 @@ end end ) - (func $~lib/rt/tlsf/insertBlock (; 2 ;) (param $0 i32) (param $1 i32) + (func $~lib/rt/tlsf/insertBlock (; 4 ;) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -580,7 +584,7 @@ local.get $7 i32.store offset=4 ) - (func $~lib/rt/tlsf/addMemory (; 3 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/rt/tlsf/addMemory (; 5 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -728,7 +732,7 @@ call $~lib/rt/tlsf/insertBlock i32.const 1 ) - (func $~lib/rt/tlsf/maybeInitialize (; 4 ;) (result i32) + (func $~lib/rt/tlsf/maybeInitialize (; 6 ;) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) @@ -882,7 +886,7 @@ end local.get $0 ) - (func $~lib/rt/tlsf/prepareSize (; 5 ;) (param $0 i32) (result i32) + (func $~lib/rt/tlsf/prepareSize (; 7 ;) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) local.get $0 @@ -911,7 +915,7 @@ i32.gt_u select ) - (func $~lib/rt/tlsf/searchBlock (; 6 ;) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/rt/tlsf/searchBlock (; 8 ;) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -1094,7 +1098,7 @@ end local.get $7 ) - (func $~lib/rt/tlsf/growMemory (; 7 ;) (param $0 i32) (param $1 i32) + (func $~lib/rt/tlsf/growMemory (; 9 ;) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -1178,7 +1182,7 @@ call $~lib/rt/tlsf/addMemory drop ) - (func $~lib/rt/tlsf/prepareBlock (; 8 ;) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/rt/tlsf/prepareBlock (; 10 ;) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1273,7 +1277,7 @@ i32.store end ) - (func $~lib/rt/tlsf/allocateBlock (; 9 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/rt/tlsf/allocateBlock (; 11 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) global.get $~lib/rt/tlsf/collectLock @@ -1381,8 +1385,10 @@ local.get $3 call $~lib/rt/tlsf/prepareBlock local.get $4 + call $~lib/rt/rtrace/onalloc + local.get $4 ) - (func $~lib/rt/tlsf/__alloc (; 10 ;) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/rt/tlsf/__alloc (; 12 ;) (param $0 i32) (param $1 i32) (result i32) call $~lib/rt/tlsf/maybeInitialize local.get $0 local.get $1 @@ -1390,9 +1396,8 @@ i32.const 16 i32.add ) - (func $std/object-literal-unmanaged/test (; 11 ;) (param $0 i32) (result i32) + (func $std/object-literal-unmanaged/test (; 13 ;) (param $0 i32) (result i32) (local $1 i32) - (local $2 i32) i32.const 4 i32.const 0 call $~lib/rt/tlsf/__alloc @@ -1401,11 +1406,79 @@ local.get $0 i32.store local.get $1 + global.set $std/object-literal-unmanaged/foo + global.get $std/object-literal-unmanaged/foo + i32.load + ) + (func $~lib/rt/tlsf/checkUsedBlock (; 14 ;) (param $0 i32) (result i32) + (local $1 i32) + local.get $0 + i32.const 16 + i32.sub + local.set $1 + local.get $0 + i32.const 0 + i32.ne + if (result i32) + local.get $0 + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $1 + i32.load + i32.const 1 + i32.and + i32.eqz + else + i32.const 0 + end + if (result i32) + local.get $1 + i32.load offset=4 + i32.const -268435456 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 581 + i32.const 3 + call $~lib/builtins/abort + unreachable + end + local.get $1 + ) + (func $~lib/rt/tlsf/freeBlock (; 15 ;) (param $0 i32) (param $1 i32) + (local $2 i32) + local.get $1 + i32.load local.set $2 + local.get $1 local.get $2 - i32.load + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $1 + call $~lib/rt/tlsf/insertBlock + local.get $1 + call $~lib/rt/rtrace/onfree + ) + (func $~lib/rt/tlsf/__free (; 16 ;) (param $0 i32) + call $~lib/rt/tlsf/maybeInitialize + local.get $0 + call $~lib/rt/tlsf/checkUsedBlock + call $~lib/rt/tlsf/freeBlock ) - (func $start:std/object-literal-unmanaged (; 12 ;) + (func $start:std/object-literal-unmanaged (; 17 ;) i32.const 123 call $std/object-literal-unmanaged/test i32.const 123 @@ -1414,16 +1487,18 @@ if i32.const 0 i32.const 144 - i32.const 11 + i32.const 13 i32.const 1 call $~lib/builtins/abort unreachable end + global.get $std/object-literal-unmanaged/foo + call $~lib/rt/tlsf/__free ) - (func $~start (; 13 ;) + (func $~start (; 18 ;) call $start:std/object-literal-unmanaged ) - (func $~lib/rt/pure/__collect (; 14 ;) + (func $~lib/rt/pure/__collect (; 19 ;) return ) )