mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-25 20:51:44 +00:00
rt hooks all over the place
still some work to do on optimizing away retain/release calls, but this looks promising
This commit is contained in:
@ -1,5 +1,3 @@
|
||||
import "allocator/arena";
|
||||
|
||||
// trailing conditional allocate
|
||||
class EmptyCtor {
|
||||
constructor() {}
|
||||
@ -46,7 +44,7 @@ var justFieldNoInit = new JustFieldNoInit();
|
||||
// explicit allocation with no extra checks
|
||||
class CtorReturns {
|
||||
constructor() {
|
||||
return changetype<CtorReturns>(memory.allocate(0));
|
||||
return changetype<CtorReturns>(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +56,7 @@ var b: bool = true;
|
||||
class CtorConditionallyReturns {
|
||||
constructor() {
|
||||
if (b) {
|
||||
return changetype<CtorConditionallyReturns>(memory.allocate(0));
|
||||
return changetype<CtorConditionallyReturns>(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,382 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$vii (func (param i32 i32)))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\16")
|
||||
(data (i32.const 80) "g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r")
|
||||
(data (i32.const 104) "\10\00\00\00\0e")
|
||||
(data (i32.const 120) "g\00c\00.\00l\00i\00n\00k")
|
||||
(data (i32.const 136) "\10\00\00\00\n")
|
||||
(data (i32.const 152) "g\00c\00.\00t\00s")
|
||||
(data (i32.const 168) "\10\00\00\00\12")
|
||||
(data (i32.const 184) "g\00c\00.\00u\00n\00l\00i\00n\00k")
|
||||
(data (i32.const 208) "\10\00\00\00\14")
|
||||
(data (i32.const 224) "g\00c\00.\00c\00o\00l\00l\00e\00c\00t")
|
||||
(global $gc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_parentRef (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/runtime/ROOT (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/main))
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
i32.const 16
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $0
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
i32.const 244
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/_dummy/__ref_link (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
|
||||
i32.const 120
|
||||
i32.const 2
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
local.get $1
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/link_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/link_ref
|
||||
local.get $0
|
||||
global.set $gc/_dummy/link_parentRef
|
||||
)
|
||||
(func $gc/_dummy/__ref_unlink (; 7 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
|
||||
i32.const 184
|
||||
i32.const 2
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
local.get $1
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/unlink_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/unlink_ref
|
||||
local.get $1
|
||||
global.set $gc/_dummy/unlink_parentRef
|
||||
)
|
||||
(func $gc/main (; 8 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 248
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 18
|
||||
call $~lib/util/runtime/register
|
||||
global.set $~lib/runtime/ROOT
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $2
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $0
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $1
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $3
|
||||
local.get $2
|
||||
global.get $~lib/runtime/ROOT
|
||||
call $gc/_dummy/__ref_link
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 15
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 16
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $3
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 17
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $0
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $1
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $3
|
||||
local.get $2
|
||||
global.get $~lib/runtime/ROOT
|
||||
call $gc/_dummy/__ref_unlink
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $0
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 24
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 25
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $3
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 26
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $2
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $0
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $1
|
||||
i32.const 224
|
||||
i32.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/collect_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/collect_count
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $2
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 33
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $0
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 34
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 35
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $null (; 9 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,36 +0,0 @@
|
||||
import "allocator/arena";
|
||||
import { link_count, unlink_count, collect_count } from "./gc/_dummy";
|
||||
|
||||
class Ref {}
|
||||
|
||||
@start export function main(): void {
|
||||
var ref = new Ref();
|
||||
|
||||
var previous_link_count = link_count;
|
||||
var previous_unlink_count = unlink_count;
|
||||
var previous_collect_count = collect_count;
|
||||
|
||||
runtime.retain(changetype<usize>(ref));
|
||||
|
||||
assert(link_count == previous_link_count + 1);
|
||||
assert(unlink_count == previous_unlink_count);
|
||||
assert(collect_count == previous_collect_count);
|
||||
previous_link_count = link_count;
|
||||
previous_unlink_count = unlink_count;
|
||||
previous_collect_count = collect_count;
|
||||
|
||||
runtime.release(changetype<usize>(ref));
|
||||
|
||||
assert(link_count == previous_link_count);
|
||||
assert(unlink_count == previous_unlink_count + 1);
|
||||
assert(collect_count == previous_collect_count);
|
||||
previous_link_count = link_count;
|
||||
previous_unlink_count = unlink_count;
|
||||
previous_collect_count = collect_count;
|
||||
|
||||
runtime.collect();
|
||||
|
||||
assert(link_count == previous_link_count);
|
||||
assert(unlink_count == previous_unlink_count);
|
||||
assert(collect_count == previous_collect_count + 1);
|
||||
}
|
@ -1,475 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$vii (func (param i32 i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r\00")
|
||||
(data (i32.const 104) "\10\00\00\00\0e\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00l\00i\00n\00k\00")
|
||||
(data (i32.const 136) "\10\00\00\00\n\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00t\00s\00")
|
||||
(data (i32.const 168) "\10\00\00\00\12\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00u\00n\00l\00i\00n\00k\00")
|
||||
(data (i32.const 208) "\10\00\00\00\14\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00c\00o\00l\00l\00e\00c\00t\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $gc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $~lib/runtime/ROOT (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 244))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/main))
|
||||
(func $~lib/util/runtime/adjust (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/Ref#constructor (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/runtime/Root#constructor (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 18
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/_dummy/__ref_link (; 10 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
|
||||
i32.const 120
|
||||
i32.const 2
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
local.get $1
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/link_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/link_ref
|
||||
local.get $0
|
||||
global.set $gc/_dummy/link_parentRef
|
||||
)
|
||||
(func $~lib/runtime/runtime.retain (; 11 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
global.get $~lib/runtime/ROOT
|
||||
call $gc/_dummy/__ref_link
|
||||
)
|
||||
(func $gc/_dummy/__ref_unlink (; 12 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
|
||||
i32.const 184
|
||||
i32.const 2
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
local.get $1
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/unlink_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/unlink_ref
|
||||
local.get $1
|
||||
global.set $gc/_dummy/unlink_parentRef
|
||||
)
|
||||
(func $~lib/runtime/runtime.release (; 13 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
global.get $~lib/runtime/ROOT
|
||||
call $gc/_dummy/__ref_unlink
|
||||
)
|
||||
(func $gc/_dummy/__ref_collect (; 14 ;) (type $FUNCSIG$v)
|
||||
i32.const 224
|
||||
i32.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/collect_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/collect_count
|
||||
)
|
||||
(func $~lib/runtime/runtime.collect (; 15 ;) (type $FUNCSIG$v)
|
||||
call $gc/_dummy/__ref_collect
|
||||
)
|
||||
(func $gc/main (; 16 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
i32.const 0
|
||||
call $gc/Ref#constructor
|
||||
local.set $0
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $1
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $2
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $3
|
||||
local.get $0
|
||||
call $~lib/runtime/runtime.retain
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 15
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 16
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $3
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 17
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $1
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $2
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $3
|
||||
local.get $0
|
||||
call $~lib/runtime/runtime.release
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 24
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 25
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $3
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 26
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
local.set $1
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.set $2
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.set $3
|
||||
call $~lib/runtime/runtime.collect
|
||||
global.get $gc/_dummy/link_count
|
||||
local.get $1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 33
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
local.get $2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 34
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/collect_count
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 152
|
||||
i32.const 35
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 17 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
i32.const 0
|
||||
call $~lib/runtime/Root#constructor
|
||||
global.set $~lib/runtime/ROOT
|
||||
)
|
||||
(func $null (; 18 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1 +0,0 @@
|
||||
Tracing GC tests
|
@ -1,58 +0,0 @@
|
||||
// A dummy tracing GC for testing.
|
||||
|
||||
export var collect_count = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_collect(): void {
|
||||
trace("gc.collect");
|
||||
collect_count++;
|
||||
}
|
||||
|
||||
export var register_count = 0;
|
||||
export var register_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_register(ref: usize): void {
|
||||
trace("gc.register", 1, ref);
|
||||
register_count++;
|
||||
register_ref = ref;
|
||||
}
|
||||
|
||||
export var link_count = 0;
|
||||
export var link_ref: usize = 0;
|
||||
export var link_parentRef: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_link(ref: usize, parentRef: usize): void {
|
||||
trace("gc.link", 2, ref, parentRef);
|
||||
link_count++;
|
||||
link_ref = ref;
|
||||
link_parentRef = ref;
|
||||
}
|
||||
|
||||
export var unlink_count = 0;
|
||||
export var unlink_ref: usize = 0;
|
||||
export var unlink_parentRef: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_unlink(ref: usize, parentRef: usize): void {
|
||||
trace("gc.unlink", 2, ref, parentRef);
|
||||
unlink_count++;
|
||||
unlink_ref = ref;
|
||||
unlink_parentRef = parentRef;
|
||||
}
|
||||
|
||||
export var mark_count = 0;
|
||||
export var mark_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_mark(ref: usize): void {
|
||||
trace("gc.mark", 1, ref);
|
||||
mark_count++;
|
||||
mark_ref = ref;
|
||||
}
|
@ -1,246 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\16")
|
||||
(data (i32.const 80) "g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r")
|
||||
(data (i32.const 104) "\10\00\00\00&")
|
||||
(data (i32.const 120) "g\00c\00/\00g\00l\00o\00b\00a\00l\00-\00a\00s\00s\00i\00g\00n\00.\00t\00s")
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $gc/global-assign/global (mut i32) (i32.const 0))
|
||||
(global $gc/global-assign/globalRef (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/global-assign/main))
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
i32.const 16
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $0
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
i32.const 160
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 17
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $start:gc/global-assign (; 6 ;) (type $FUNCSIG$v)
|
||||
i32.const 160
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
global.set $gc/global-assign/global
|
||||
global.get $gc/global-assign/global
|
||||
global.set $gc/global-assign/globalRef
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
global.set $gc/global-assign/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 19
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/global-assign/main (; 7 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start:gc/global-assign
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $null (; 8 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,21 +0,0 @@
|
||||
import "allocator/arena";
|
||||
import { register_count, link_count, unlink_count } from "./_dummy";
|
||||
|
||||
@start export function main(): void {}
|
||||
|
||||
class Ref {}
|
||||
|
||||
// should register only
|
||||
|
||||
var global: Ref = new Ref();
|
||||
var globalRef = changetype<usize>(global);
|
||||
assert(register_count == 1);
|
||||
assert(link_count == 0);
|
||||
assert(unlink_count == 0);
|
||||
|
||||
// should register only
|
||||
|
||||
global = new Ref();
|
||||
assert(register_count == 2);
|
||||
assert(link_count == 0);
|
||||
assert(unlink_count == 0);
|
@ -1,329 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r\00")
|
||||
(data (i32.const 104) "\10\00\00\00&\00\00\00\00\00\00\00\00\00\00\00g\00c\00/\00g\00l\00o\00b\00a\00l\00-\00a\00s\00s\00i\00g\00n\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $gc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $gc/global-assign/global (mut i32) (i32.const 0))
|
||||
(global $gc/global-assign/globalRef (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 160))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/global-assign/main))
|
||||
(func $~lib/util/runtime/adjust (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/global-assign/Ref#constructor (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $start:gc/global-assign (; 9 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
i32.const 0
|
||||
call $gc/global-assign/Ref#constructor
|
||||
global.set $gc/global-assign/global
|
||||
global.get $gc/global-assign/global
|
||||
global.set $gc/global-assign/globalRef
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $gc/global-assign/Ref#constructor
|
||||
global.set $gc/global-assign/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 19
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/global-assign/main (; 10 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $start (; 11 ;) (type $FUNCSIG$v)
|
||||
call $start:gc/global-assign
|
||||
)
|
||||
(func $null (; 12 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\16")
|
||||
(data (i32.const 80) "g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r")
|
||||
(data (i32.const 104) "\10\00\00\00\"")
|
||||
(data (i32.const 120) "g\00c\00/\00g\00l\00o\00b\00a\00l\00-\00i\00n\00i\00t\00.\00t\00s")
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $gc/global-init/global (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/global-init/main))
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
i32.const 16
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $0
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
i32.const 156
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 17
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $start:gc/global-init (; 6 ;) (type $FUNCSIG$v)
|
||||
i32.const 160
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
global.set $gc/global-init/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 11
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
global.set $gc/global-init/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 16
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 17
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 18
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/global-init/main (; 7 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start:gc/global-init
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $null (; 8 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,18 +0,0 @@
|
||||
import "allocator/arena";
|
||||
import { register_count, link_count, unlink_count } from "./_dummy";
|
||||
|
||||
@start export function main(): void {}
|
||||
|
||||
class Ref {}
|
||||
|
||||
// should register only
|
||||
|
||||
var global: Ref = new Ref();
|
||||
assert(register_count == 1);
|
||||
assert(link_count == 0);
|
||||
assert(unlink_count == 0);
|
||||
|
||||
global = new Ref();
|
||||
assert(register_count == 2);
|
||||
assert(link_count == 0);
|
||||
assert(unlink_count == 0);
|
@ -1,326 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r\00")
|
||||
(data (i32.const 104) "\10\00\00\00\"\00\00\00\00\00\00\00\00\00\00\00g\00c\00/\00g\00l\00o\00b\00a\00l\00-\00i\00n\00i\00t\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $gc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/link_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_ref (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/unlink_parentRef (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_count (mut i32) (i32.const 0))
|
||||
(global $gc/_dummy/mark_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $gc/global-init/global (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 156))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/global-init/main))
|
||||
(func $~lib/util/runtime/adjust (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $gc/_dummy/__ref_register (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/global-init/Ref#constructor (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $start:gc/global-init (; 9 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
i32.const 0
|
||||
call $gc/global-init/Ref#constructor
|
||||
global.set $gc/global-init/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 11
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $gc/global-init/Ref#constructor
|
||||
global.set $gc/global-init/global
|
||||
global.get $gc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 16
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/link_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 17
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/_dummy/unlink_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 120
|
||||
i32.const 18
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/global-init/main (; 10 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $start (; 11 ;) (type $FUNCSIG$v)
|
||||
call $start:gc/global-init
|
||||
)
|
||||
(func $null (; 12 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,31 +0,0 @@
|
||||
@global const GC_TRACE = true;
|
||||
import "allocator/arena";
|
||||
import "collector/itcm";
|
||||
|
||||
import { HEADER_SIZE } from "util/runtime";
|
||||
|
||||
assert(HEADER_SIZE == 16);
|
||||
|
||||
class Ref {
|
||||
inner: Ref;
|
||||
}
|
||||
|
||||
function makeGarbage(): void {
|
||||
trace("# ref = new Ref()");
|
||||
var ref = new Ref();
|
||||
trace("# arr = new Array(1)");
|
||||
var arr = new Array<Ref | null>(1);
|
||||
trace("# arr[0] = ref");
|
||||
arr[0] = ref;
|
||||
trace("# arr[0] = null");
|
||||
arr[0] = null;
|
||||
trace("# new Ref()");
|
||||
new Ref();
|
||||
}
|
||||
|
||||
makeGarbage();
|
||||
runtime.collect();
|
||||
|
||||
// should have sweeped four objects (incl. arr.buffer)
|
||||
|
||||
@start export function main(): void {}
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
Reference counting GC tests
|
@ -1,43 +0,0 @@
|
||||
// A dummy reference counting GC for testing.
|
||||
|
||||
export var collect_count = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_collect(): void {
|
||||
trace("gc.collect");
|
||||
collect_count++;
|
||||
}
|
||||
|
||||
export var register_count = 0;
|
||||
export var register_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_register(ref: usize): void {
|
||||
trace("gc.register", 1, ref);
|
||||
register_count++;
|
||||
register_ref = ref;
|
||||
}
|
||||
|
||||
export var retain_count = 0;
|
||||
export var retain_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_retain(ref: usize): void {
|
||||
trace("gc.retain", 1, ref);
|
||||
retain_count++;
|
||||
retain_ref = ref;
|
||||
}
|
||||
|
||||
export var release_count = 0;
|
||||
export var release_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __ref_release(ref: usize): void {
|
||||
trace("gc.release", 1, ref);
|
||||
release_count++;
|
||||
release_ref = ref;
|
||||
}
|
@ -1,345 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\16")
|
||||
(data (i32.const 80) "g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r")
|
||||
(data (i32.const 104) "\10\00\00\00\12")
|
||||
(data (i32.const 120) "g\00c\00.\00r\00e\00t\00a\00i\00n")
|
||||
(data (i32.const 144) "\10\00\00\00,")
|
||||
(data (i32.const 160) "g\00c\00/\00r\00c\00/\00g\00l\00o\00b\00a\00l\00-\00a\00s\00s\00i\00g\00n\00.\00t\00s")
|
||||
(data (i32.const 208) "\10\00\00\00\14")
|
||||
(data (i32.const 224) "g\00c\00.\00r\00e\00l\00e\00a\00s\00e")
|
||||
(global $gc/rc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $gc/rc/global-assign/global (mut i32) (i32.const 0))
|
||||
(global $gc/rc/global-assign/globalRef (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/rc/global-assign/main))
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
i32.const 16
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $0
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_register (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
i32.const 244
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 17
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_retain (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 120
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/retain_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/retain_ref
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_release (; 7 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 224
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/release_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/release_ref
|
||||
)
|
||||
(func $start:gc/rc/global-assign (; 8 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 248
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
local.tee $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
local.get $0
|
||||
global.set $gc/rc/global-assign/global
|
||||
global.get $gc/rc/global-assign/global
|
||||
global.set $gc/rc/global-assign/globalRef
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-assign/globalRef
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 15
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
local.get $0
|
||||
global.get $gc/rc/global-assign/global
|
||||
local.tee $1
|
||||
i32.ne
|
||||
if
|
||||
local.get $1
|
||||
if
|
||||
local.get $1
|
||||
call $gc/rc/_dummy/__ref_release
|
||||
end
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
end
|
||||
local.get $0
|
||||
global.set $gc/rc/global-assign/global
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 2
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-assign/global
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 22
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 23
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_ref
|
||||
global.get $gc/rc/global-assign/globalRef
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 24
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/rc/global-assign/main (; 9 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start:gc/rc/global-assign
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $null (; 10 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,24 +0,0 @@
|
||||
import "allocator/arena";
|
||||
import { register_count, retain_count, retain_ref, release_count, release_ref } from "./_dummy";
|
||||
|
||||
@start export function main(): void {}
|
||||
|
||||
class Ref {}
|
||||
|
||||
// should register and retain
|
||||
|
||||
var global: Ref = new Ref();
|
||||
var globalRef = changetype<usize>(global);
|
||||
assert(register_count == 1);
|
||||
assert(retain_count == 1);
|
||||
assert(retain_ref == globalRef);
|
||||
assert(release_count == 0);
|
||||
|
||||
// should register, release old and retain new
|
||||
|
||||
global = new Ref();
|
||||
assert(register_count == 2);
|
||||
assert(retain_count == 2);
|
||||
assert(retain_ref == changetype<usize>(global));
|
||||
assert(release_count == 1);
|
||||
assert(release_ref == globalRef);
|
@ -1,421 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r\00")
|
||||
(data (i32.const 104) "\10\00\00\00\12\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00t\00a\00i\00n\00")
|
||||
(data (i32.const 144) "\10\00\00\00,\00\00\00\00\00\00\00\00\00\00\00g\00c\00/\00r\00c\00/\00g\00l\00o\00b\00a\00l\00-\00a\00s\00s\00i\00g\00n\00.\00t\00s\00")
|
||||
(data (i32.const 208) "\10\00\00\00\14\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00l\00e\00a\00s\00e\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $gc/rc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $gc/rc/global-assign/global (mut i32) (i32.const 0))
|
||||
(global $gc/rc/global-assign/globalRef (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 244))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/rc/global-assign/main))
|
||||
(func $~lib/util/runtime/adjust (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_register (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/global-assign/Ref#constructor (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_retain (; 9 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 120
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/retain_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/retain_ref
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_release (; 10 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 224
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/release_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/release_ref
|
||||
)
|
||||
(func $start:gc/rc/global-assign (; 11 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
call $gc/rc/global-assign/Ref#constructor
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
local.get $0
|
||||
end
|
||||
global.set $gc/rc/global-assign/global
|
||||
global.get $gc/rc/global-assign/global
|
||||
global.set $gc/rc/global-assign/globalRef
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-assign/globalRef
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 15
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $gc/rc/global-assign/Ref#constructor
|
||||
local.tee $0
|
||||
global.get $gc/rc/global-assign/global
|
||||
local.tee $1
|
||||
i32.ne
|
||||
if (result i32)
|
||||
local.get $1
|
||||
if
|
||||
local.get $1
|
||||
call $gc/rc/_dummy/__ref_release
|
||||
end
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
local.get $0
|
||||
else
|
||||
local.get $0
|
||||
end
|
||||
global.set $gc/rc/global-assign/global
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-assign/global
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 22
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 23
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_ref
|
||||
global.get $gc/rc/global-assign/globalRef
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 24
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/rc/global-assign/main (; 12 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $start (; 13 ;) (type $FUNCSIG$v)
|
||||
call $start:gc/rc/global-assign
|
||||
)
|
||||
(func $null (; 14 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\16")
|
||||
(data (i32.const 80) "g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r")
|
||||
(data (i32.const 104) "\10\00\00\00\12")
|
||||
(data (i32.const 120) "g\00c\00.\00r\00e\00t\00a\00i\00n")
|
||||
(data (i32.const 144) "\10\00\00\00(")
|
||||
(data (i32.const 160) "g\00c\00/\00r\00c\00/\00g\00l\00o\00b\00a\00l\00-\00i\00n\00i\00t\00.\00t\00s")
|
||||
(global $gc/rc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_count (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $gc/rc/global-init/global (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/rc/global-init/main))
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
i32.const 16
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $0
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_register (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
i32.const 200
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 17
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_retain (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 120
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/retain_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/retain_ref
|
||||
)
|
||||
(func $start:gc/rc/global-init (; 7 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 200
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/util/runtime/register
|
||||
local.tee $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
local.get $0
|
||||
global.set $gc/rc/global-init/global
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 11
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-init/global
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/rc/global-init/main (; 8 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start:gc/rc/global-init
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $null (; 9 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,14 +0,0 @@
|
||||
import "allocator/arena";
|
||||
import { register_count, retain_count, retain_ref, release_count } from "./_dummy";
|
||||
|
||||
@start export function main(): void {}
|
||||
|
||||
class Ref {}
|
||||
|
||||
// should register and retain, with nothing to release
|
||||
|
||||
var global = new Ref();
|
||||
assert(register_count == 1);
|
||||
assert(retain_count == 1);
|
||||
assert(retain_ref == changetype<usize>(global));
|
||||
assert(release_count == 0);
|
@ -1,320 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiddddd (func (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(import "env" "trace" (func $~lib/builtins/trace (param i32 i32 f64 f64 f64 f64 f64)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\16\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00g\00i\00s\00t\00e\00r\00")
|
||||
(data (i32.const 104) "\10\00\00\00\12\00\00\00\00\00\00\00\00\00\00\00g\00c\00.\00r\00e\00t\00a\00i\00n\00")
|
||||
(data (i32.const 144) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00g\00c\00/\00r\00c\00/\00g\00l\00o\00b\00a\00l\00-\00i\00n\00i\00t\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $gc/rc/_dummy/collect_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/register_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/retain_ref (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_count (mut i32) (i32.const 0))
|
||||
(global $gc/rc/_dummy/release_ref (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $gc/rc/global-init/global (mut i32) (i32.const 0))
|
||||
(global $~lib/started (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 200))
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $gc/rc/global-init/main))
|
||||
(func $~lib/util/runtime/adjust (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_register (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 80
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/register_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/register_ref
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_register
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/global-init/Ref#constructor (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/util/runtime/allocate
|
||||
i32.const 17
|
||||
call $~lib/util/runtime/register
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $gc/rc/_dummy/__ref_retain (; 9 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 120
|
||||
i32.const 1
|
||||
local.get $0
|
||||
f64.convert_i32_u
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
f64.const 0
|
||||
call $~lib/builtins/trace
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $gc/rc/_dummy/retain_count
|
||||
local.get $0
|
||||
global.set $gc/rc/_dummy/retain_ref
|
||||
)
|
||||
(func $start:gc/rc/global-init (; 10 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
call $gc/rc/global-init/Ref#constructor
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $gc/rc/_dummy/__ref_retain
|
||||
local.get $0
|
||||
end
|
||||
global.set $gc/rc/global-init/global
|
||||
global.get $gc/rc/_dummy/register_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 11
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_count
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/retain_ref
|
||||
global.get $gc/rc/global-init/global
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $gc/rc/_dummy/release_count
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 160
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $gc/rc/global-init/main (; 11 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/started
|
||||
i32.eqz
|
||||
if
|
||||
call $start
|
||||
i32.const 1
|
||||
global.set $~lib/started
|
||||
end
|
||||
)
|
||||
(func $start (; 12 ;) (type $FUNCSIG$v)
|
||||
call $start:gc/rc/global-init
|
||||
)
|
||||
(func $null (; 13 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,10 +1,9 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$iijijij (func (param i32 i64 i32 i64 i32 i64) (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
@ -15,52 +14,50 @@
|
||||
(data (i32.const 48) "0\000\000\001\000\002\000\003\000\004\000\005\000\006\000\007\000\008\000\009\001\000\001\001\001\002\001\003\001\004\001\005\001\006\001\007\001\008\001\009\002\000\002\001\002\002\002\003\002\004\002\005\002\006\002\007\002\008\002\009\003\000\003\001\003\002\003\003\003\004\003\005\003\006\003\007\003\008\003\009\004\000\004\001\004\002\004\003\004\004\004\005\004\006\004\007\004\008\004\009\005\000\005\001\005\002\005\003\005\004\005\005\005\006\005\007\005\008\005\009\006\000\006\001\006\002\006\003\006\004\006\005\006\006\006\007\006\008\006\009\007\000\007\001\007\002\007\003\007\004\007\005\007\006\007\007\007\008\007\009\008\000\008\001\008\002\008\003\008\004\008\005\008\006\008\007\008\008\008\009\009\000\009\001\009\002\009\003\009\004\009\005\009\006\009\007\009\008\009\009")
|
||||
(data (i32.const 448) "\11\00\00\00\10")
|
||||
(data (i32.const 464) "0\00\00\000\00\00\00\90\01\00\00d")
|
||||
(data (i32.const 480) "\10\00\00\00(")
|
||||
(data (i32.const 496) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 536) "\10\00\00\00\02")
|
||||
(data (i32.const 552) "1")
|
||||
(data (i32.const 560) "\10\00\00\00\12")
|
||||
(data (i32.const 576) "n\00u\00m\00b\00e\00r\00.\00t\00s")
|
||||
(data (i32.const 600) "\10\00\00\00\06")
|
||||
(data (i32.const 616) "0\00.\000")
|
||||
(data (i32.const 624) "\10\00\00\00\06")
|
||||
(data (i32.const 640) "N\00a\00N")
|
||||
(data (i32.const 648) "\10\00\00\00\12")
|
||||
(data (i32.const 664) "-\00I\00n\00f\00i\00n\00i\00t\00y")
|
||||
(data (i32.const 688) "\10\00\00\00\10")
|
||||
(data (i32.const 704) "I\00n\00f\00i\00n\00i\00t\00y")
|
||||
(data (i32.const 720) "\0f\00\00\00\b8\02")
|
||||
(data (i32.const 736) "\88\02\1c\08\a0\d5\8f\fav\bf>\a2\7f\e1\ae\bav\acU0 \fb\16\8b\ea5\ce]J\89B\cf-;eU\aa\b0k\9a\dfE\1a=\03\cf\1a\e6\ca\c6\9a\c7\17\fep\abO\dc\bc\be\fc\b1w\ff\0c\d6kA\ef\91V\be<\fc\7f\90\ad\1f\d0\8d\83\9aU1(\\Q\d3\b5\c9\a6\ad\8f\acq\9d\cb\8b\ee#w\"\9c\eamSx@\91I\cc\aeW\ce\b6]y\12<\827V\fbM6\94\10\c2O\98H8o\ea\96\90\c7:\82%\cb\85t\d7\f4\97\bf\97\cd\cf\86\a0\e5\ac*\17\98\n4\ef\8e\b25*\fbg8\b2;?\c6\d2\df\d4\c8\84\ba\cd\d3\1a\'D\dd\c5\96\c9%\bb\ce\9fk\93\84\a5b}$l\ac\db\f6\da_\0dXf\ab\a3&\f1\c3\de\93\f8\e2\f3\b8\80\ff\aa\a8\ad\b5\b5\8bJ|l\05_b\87S0\c14`\ff\bc\c9U&\ba\91\8c\85N\96\bd~)p$w\f9\df\8f\b8\e5\b8\9f\bd\df\a6\94}t\88\cf_\a9\f8\cf\9b\a8\8f\93pD\b9k\15\0f\bf\f8\f0\08\8a\b611eU%\b0\cd\ac\7f{\d0\c6\e2?\99\06;+*\c4\10\\\e4\d3\92si\99$$\aa\0e\ca\00\83\f2\b5\87\fd\eb\1a\11\92d\08\e5\bc\cc\88Po\t\cc\bc\8c,e\19\e2X\17\b7\d1\00\00\00\00\00\00@\9c\00\00\00\00\10\a5\d4\e8\00\00b\ac\c5\ebx\ad\84\t\94\f8x9?\81\b3\15\07\c9{\ce\97\c0p\\\ea{\ce2~\8fh\80\e9\ab\a48\d2\d5E\"\9a\17&\'O\9f\'\fb\c4\d41\a2c\ed\a8\ad\c8\8c8e\de\b0\dbe\ab\1a\8e\08\c7\83\9a\1dqB\f9\1d]\c4X\e7\1b\a6,iM\92\ea\8dp\1ad\ee\01\daJw\ef\9a\99\a3m\a2\85k}\b4{x\t\f2w\18\ddy\a1\e4T\b4\c2\c5\9b[\92\86[\86=]\96\c8\c5S5\c8\b3\a0\97\fa\\\b4*\95\e3_\a0\99\bd\9fF\de%\8c9\db4\c2\9b\a5\\\9f\98\a3r\9a\c6\f6\ce\be\e9TS\bf\dc\b7\e2A\"\f2\17\f3\fc\88\a5x\\\d3\9b\ce \cc\dfS!{\f3Z\16\98:0\1f\97\dc\b5\a0\e2\96\b3\e3\\S\d1\d9\a8<D\a7\a4\d9|\9b\fb\10D\a4\a7LLv\bb\1a\9c@\b6\ef\8e\ab\8b,\84W\a6\10\ef\1f\d0)1\91\e9\e5\a4\10\9b\9d\0c\9c\a1\fb\9b\10\e7)\f4;b\d9 (\ac\85\cf\a7z^KD\80-\dd\ac\03@\e4!\bf\8f\ffD^/\9cg\8eA\b8\8c\9c\9d\173\d4\a9\1b\e3\b4\92\db\19\9e\d9w\df\ban\bf\96\ebk\ee\f0\9b;\02\87\af")
|
||||
(data (i32.const 1432) "\12\00\00\00\10")
|
||||
(data (i32.const 1448) "\e0\02\00\00\e0\02\00\00\b8\02\00\00W")
|
||||
(data (i32.const 1464) "\0f\00\00\00\ae")
|
||||
(data (i32.const 1480) "<\fbW\fbr\fb\8c\fb\a7\fb\c1\fb\dc\fb\f6\fb\11\fc,\fcF\fca\fc{\fc\96\fc\b1\fc\cb\fc\e6\fc\00\fd\1b\fd5\fdP\fdk\fd\85\fd\a0\fd\ba\fd\d5\fd\ef\fd\n\fe%\fe?\feZ\fet\fe\8f\fe\a9\fe\c4\fe\df\fe\f9\fe\14\ff.\ffI\ffc\ff~\ff\99\ff\b3\ff\ce\ff\e8\ff\03\00\1e\008\00S\00m\00\88\00\a2\00\bd\00\d8\00\f2\00\0d\01\'\01B\01\\\01w\01\92\01\ac\01\c7\01\e1\01\fc\01\16\021\02L\02f\02\81\02\9b\02\b6\02\d0\02\eb\02\06\03 \03;\03U\03p\03\8b\03\a5\03\c0\03\da\03\f5\03\0f\04*\04")
|
||||
(data (i32.const 1656) "\13\00\00\00\10")
|
||||
(data (i32.const 1672) "\c8\05\00\00\c8\05\00\00\ae\00\00\00W")
|
||||
(data (i32.const 1688) "\0f\00\00\00(")
|
||||
(data (i32.const 1704) "\01\00\00\00\n\00\00\00d\00\00\00\e8\03\00\00\10\'\00\00\a0\86\01\00@B\0f\00\80\96\98\00\00\e1\f5\05\00\ca\9a;")
|
||||
(data (i32.const 1744) "\11\00\00\00\10")
|
||||
(data (i32.const 1760) "\a8\06\00\00\a8\06\00\00(\00\00\00\n")
|
||||
(data (i32.const 1776) "\10\00\00\00\1c")
|
||||
(data (i32.const 1792) "~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s")
|
||||
(data (i32.const 1824) "\10")
|
||||
(data (i32.const 1840) "\10\00\00\00\06")
|
||||
(data (i32.const 1856) "2\00.\000")
|
||||
(data (i32.const 1864) "\10\00\00\00\02")
|
||||
(data (i32.const 1880) "3")
|
||||
(data (i32.const 1888) "\10\00\00\00\04")
|
||||
(data (i32.const 1904) "-\005")
|
||||
(data (i32.const 1912) "\10\00\00\00\02")
|
||||
(data (i32.const 1928) "4")
|
||||
(data (i32.const 1936) "\10\00\00\00\02")
|
||||
(data (i32.const 1952) "2")
|
||||
(data (i32.const 1960) "\10\00\00\00\08")
|
||||
(data (i32.const 1976) "t\00r\00u\00e")
|
||||
(data (i32.const 1984) "\10\00\00\00\n")
|
||||
(data (i32.const 2000) "f\00a\00l\00s\00e")
|
||||
(data (i32.const 480) "\10\00\00\00\02")
|
||||
(data (i32.const 496) "1")
|
||||
(data (i32.const 504) "\10\00\00\00\12")
|
||||
(data (i32.const 520) "n\00u\00m\00b\00e\00r\00.\00t\00s")
|
||||
(data (i32.const 544) "\10\00\00\00\06")
|
||||
(data (i32.const 560) "0\00.\000")
|
||||
(data (i32.const 568) "\10\00\00\00\06")
|
||||
(data (i32.const 584) "N\00a\00N")
|
||||
(data (i32.const 592) "\10\00\00\00\12")
|
||||
(data (i32.const 608) "-\00I\00n\00f\00i\00n\00i\00t\00y")
|
||||
(data (i32.const 632) "\10\00\00\00\10")
|
||||
(data (i32.const 648) "I\00n\00f\00i\00n\00i\00t\00y")
|
||||
(data (i32.const 664) "\0f\00\00\00\b8\02")
|
||||
(data (i32.const 680) "\88\02\1c\08\a0\d5\8f\fav\bf>\a2\7f\e1\ae\bav\acU0 \fb\16\8b\ea5\ce]J\89B\cf-;eU\aa\b0k\9a\dfE\1a=\03\cf\1a\e6\ca\c6\9a\c7\17\fep\abO\dc\bc\be\fc\b1w\ff\0c\d6kA\ef\91V\be<\fc\7f\90\ad\1f\d0\8d\83\9aU1(\\Q\d3\b5\c9\a6\ad\8f\acq\9d\cb\8b\ee#w\"\9c\eamSx@\91I\cc\aeW\ce\b6]y\12<\827V\fbM6\94\10\c2O\98H8o\ea\96\90\c7:\82%\cb\85t\d7\f4\97\bf\97\cd\cf\86\a0\e5\ac*\17\98\n4\ef\8e\b25*\fbg8\b2;?\c6\d2\df\d4\c8\84\ba\cd\d3\1a\'D\dd\c5\96\c9%\bb\ce\9fk\93\84\a5b}$l\ac\db\f6\da_\0dXf\ab\a3&\f1\c3\de\93\f8\e2\f3\b8\80\ff\aa\a8\ad\b5\b5\8bJ|l\05_b\87S0\c14`\ff\bc\c9U&\ba\91\8c\85N\96\bd~)p$w\f9\df\8f\b8\e5\b8\9f\bd\df\a6\94}t\88\cf_\a9\f8\cf\9b\a8\8f\93pD\b9k\15\0f\bf\f8\f0\08\8a\b611eU%\b0\cd\ac\7f{\d0\c6\e2?\99\06;+*\c4\10\\\e4\d3\92si\99$$\aa\0e\ca\00\83\f2\b5\87\fd\eb\1a\11\92d\08\e5\bc\cc\88Po\t\cc\bc\8c,e\19\e2X\17\b7\d1\00\00\00\00\00\00@\9c\00\00\00\00\10\a5\d4\e8\00\00b\ac\c5\ebx\ad\84\t\94\f8x9?\81\b3\15\07\c9{\ce\97\c0p\\\ea{\ce2~\8fh\80\e9\ab\a48\d2\d5E\"\9a\17&\'O\9f\'\fb\c4\d41\a2c\ed\a8\ad\c8\8c8e\de\b0\dbe\ab\1a\8e\08\c7\83\9a\1dqB\f9\1d]\c4X\e7\1b\a6,iM\92\ea\8dp\1ad\ee\01\daJw\ef\9a\99\a3m\a2\85k}\b4{x\t\f2w\18\ddy\a1\e4T\b4\c2\c5\9b[\92\86[\86=]\96\c8\c5S5\c8\b3\a0\97\fa\\\b4*\95\e3_\a0\99\bd\9fF\de%\8c9\db4\c2\9b\a5\\\9f\98\a3r\9a\c6\f6\ce\be\e9TS\bf\dc\b7\e2A\"\f2\17\f3\fc\88\a5x\\\d3\9b\ce \cc\dfS!{\f3Z\16\98:0\1f\97\dc\b5\a0\e2\96\b3\e3\\S\d1\d9\a8<D\a7\a4\d9|\9b\fb\10D\a4\a7LLv\bb\1a\9c@\b6\ef\8e\ab\8b,\84W\a6\10\ef\1f\d0)1\91\e9\e5\a4\10\9b\9d\0c\9c\a1\fb\9b\10\e7)\f4;b\d9 (\ac\85\cf\a7z^KD\80-\dd\ac\03@\e4!\bf\8f\ffD^/\9cg\8eA\b8\8c\9c\9d\173\d4\a9\1b\e3\b4\92\db\19\9e\d9w\df\ban\bf\96\ebk\ee\f0\9b;\02\87\af")
|
||||
(data (i32.const 1376) "\12\00\00\00\10")
|
||||
(data (i32.const 1392) "\a8\02\00\00\a8\02\00\00\b8\02\00\00W")
|
||||
(data (i32.const 1408) "\0f\00\00\00\ae")
|
||||
(data (i32.const 1424) "<\fbW\fbr\fb\8c\fb\a7\fb\c1\fb\dc\fb\f6\fb\11\fc,\fcF\fca\fc{\fc\96\fc\b1\fc\cb\fc\e6\fc\00\fd\1b\fd5\fdP\fdk\fd\85\fd\a0\fd\ba\fd\d5\fd\ef\fd\n\fe%\fe?\feZ\fet\fe\8f\fe\a9\fe\c4\fe\df\fe\f9\fe\14\ff.\ffI\ffc\ff~\ff\99\ff\b3\ff\ce\ff\e8\ff\03\00\1e\008\00S\00m\00\88\00\a2\00\bd\00\d8\00\f2\00\0d\01\'\01B\01\\\01w\01\92\01\ac\01\c7\01\e1\01\fc\01\16\021\02L\02f\02\81\02\9b\02\b6\02\d0\02\eb\02\06\03 \03;\03U\03p\03\8b\03\a5\03\c0\03\da\03\f5\03\0f\04*\04")
|
||||
(data (i32.const 1600) "\13\00\00\00\10")
|
||||
(data (i32.const 1616) "\90\05\00\00\90\05\00\00\ae\00\00\00W")
|
||||
(data (i32.const 1632) "\0f\00\00\00(")
|
||||
(data (i32.const 1648) "\01\00\00\00\n\00\00\00d\00\00\00\e8\03\00\00\10\'\00\00\a0\86\01\00@B\0f\00\80\96\98\00\00\e1\f5\05\00\ca\9a;")
|
||||
(data (i32.const 1688) "\11\00\00\00\10")
|
||||
(data (i32.const 1704) "p\06\00\00p\06\00\00(\00\00\00\n")
|
||||
(data (i32.const 1720) "\10\00\00\00\1c")
|
||||
(data (i32.const 1736) "~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s")
|
||||
(data (i32.const 1768) "\10")
|
||||
(data (i32.const 1784) "\10\00\00\00\06")
|
||||
(data (i32.const 1800) "2\00.\000")
|
||||
(data (i32.const 1808) "\10\00\00\00\02")
|
||||
(data (i32.const 1824) "3")
|
||||
(data (i32.const 1832) "\10\00\00\00\04")
|
||||
(data (i32.const 1848) "-\005")
|
||||
(data (i32.const 1856) "\10\00\00\00\02")
|
||||
(data (i32.const 1872) "4")
|
||||
(data (i32.const 1880) "\10\00\00\00\02")
|
||||
(data (i32.const 1896) "2")
|
||||
(data (i32.const 1904) "\10\00\00\00\08")
|
||||
(data (i32.const 1920) "t\00r\00u\00e")
|
||||
(data (i32.const 1928) "\10\00\00\00\n")
|
||||
(data (i32.const 1944) "f\00a\00l\00s\00e")
|
||||
(global $number/a (mut i32) (i32.const 1))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/number/_frc_plus (mut i64) (i64.const 0))
|
||||
(global $~lib/util/number/_frc_minus (mut i64) (i64.const 0))
|
||||
(global $~lib/util/number/_exp (mut i32) (i32.const 0))
|
||||
@ -123,18 +120,21 @@
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(func $~lib/rt/index-stub/__alloc (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
global.get $~lib/rt/index-stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
@ -142,20 +142,20 @@
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.const -16
|
||||
i32.and
|
||||
local.tee $0
|
||||
local.tee $1
|
||||
current_memory
|
||||
local.tee $2
|
||||
local.tee $3
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $3
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
@ -163,16 +163,16 @@
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
@ -181,32 +181,20 @@
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $1
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.add
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.const 16
|
||||
i32.store offset=8
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/util/number/utoa32_lut (; 4 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(func $~lib/util/number/utoa32_lut (; 3 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
i32.const 468
|
||||
@ -316,40 +304,7 @@
|
||||
i32.store16
|
||||
end
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
i32.const 2012
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 496
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $1
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 496
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.store
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/util/number/itoa32 (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(func $~lib/util/number/itoa32 (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
@ -376,7 +331,7 @@
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
i32.shl
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/rt/index-stub/__alloc
|
||||
local.tee $2
|
||||
local.get $0
|
||||
local.get $3
|
||||
@ -388,9 +343,8 @@
|
||||
i32.store16
|
||||
end
|
||||
local.get $2
|
||||
call $~lib/util/runtime/register
|
||||
)
|
||||
(func $~lib/util/string/compareImpl (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
(func $~lib/util/string/compareImpl (; 5 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
(local $3 i32)
|
||||
loop $continue|0
|
||||
local.get $2
|
||||
@ -423,7 +377,7 @@
|
||||
end
|
||||
local.get $3
|
||||
)
|
||||
(func $~lib/string/String.__eq (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(func $~lib/string/String.__eq (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
local.get $1
|
||||
@ -432,40 +386,38 @@
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $1
|
||||
i32.eqz
|
||||
i32.const 1
|
||||
local.get $0
|
||||
select
|
||||
if
|
||||
i32.const 0
|
||||
block $folding-inner0
|
||||
local.get $1
|
||||
i32.eqz
|
||||
i32.const 1
|
||||
local.get $0
|
||||
select
|
||||
br_if $folding-inner0
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=12
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
local.tee $2
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=12
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
i32.ne
|
||||
br_if $folding-inner0
|
||||
local.get $0
|
||||
local.get $1
|
||||
local.get $2
|
||||
call $~lib/util/string/compareImpl
|
||||
i32.eqz
|
||||
return
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
local.tee $2
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
return
|
||||
end
|
||||
local.get $0
|
||||
local.get $1
|
||||
local.get $2
|
||||
call $~lib/util/string/compareImpl
|
||||
i32.eqz
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/util/number/genDigits (; 9 ;) (type $FUNCSIG$iijijij) (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i64) (param $4 i32) (param $5 i64) (result i32)
|
||||
(func $~lib/util/number/genDigits (; 7 ;) (type $FUNCSIG$iijijij) (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i64) (param $4 i32) (param $5 i64) (result i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i64)
|
||||
@ -503,7 +455,7 @@
|
||||
local.tee $6
|
||||
call $~lib/util/number/decimalCount32
|
||||
local.set $4
|
||||
i32.const 1764
|
||||
i32.const 1708
|
||||
i32.load
|
||||
local.set $12
|
||||
loop $continue|0
|
||||
@ -871,7 +823,7 @@
|
||||
i32.store16
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 10 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(func $~lib/memory/memory.copy (; 8 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
@ -1042,7 +994,7 @@
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/util/number/prettify (; 11 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
(func $~lib/util/number/prettify (; 9 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
(local $3 i32)
|
||||
local.get $2
|
||||
i32.eqz
|
||||
@ -1293,7 +1245,7 @@
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/util/number/dtoa_core (; 12 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(func $~lib/util/number/dtoa_core (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i64)
|
||||
(local $2 i64)
|
||||
(local $3 i64)
|
||||
@ -1332,7 +1284,7 @@
|
||||
i32.shl
|
||||
i32.sub
|
||||
global.set $~lib/util/number/_K
|
||||
i32.const 1452
|
||||
i32.const 1396
|
||||
i32.load
|
||||
local.get $4
|
||||
i32.const 3
|
||||
@ -1340,7 +1292,7 @@
|
||||
i32.add
|
||||
i64.load
|
||||
global.set $~lib/util/number/_frc_pow
|
||||
i32.const 1676
|
||||
i32.const 1620
|
||||
i32.load
|
||||
local.get $4
|
||||
i32.const 1
|
||||
@ -1470,15 +1422,15 @@
|
||||
global.get $~lib/util/number/_K
|
||||
call $~lib/util/number/prettify
|
||||
)
|
||||
(func $~lib/string/String#substring (; 13 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(func $~lib/string/String#substring (; 11 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 1792
|
||||
i32.const 203
|
||||
i32.const 1736
|
||||
i32.const 196
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
@ -1487,7 +1439,7 @@
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
i32.load offset=12
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
local.tee $2
|
||||
@ -1529,7 +1481,7 @@
|
||||
local.tee $2
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 1840
|
||||
i32.const 1784
|
||||
return
|
||||
end
|
||||
local.get $3
|
||||
@ -1539,7 +1491,7 @@
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
i32.load offset=12
|
||||
i32.const 1
|
||||
i32.shr_u
|
||||
i32.const 1
|
||||
@ -1552,7 +1504,7 @@
|
||||
return
|
||||
end
|
||||
local.get $2
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/rt/index-stub/__alloc
|
||||
local.tee $1
|
||||
local.get $0
|
||||
local.get $3
|
||||
@ -1560,73 +1512,47 @@
|
||||
local.get $2
|
||||
call $~lib/memory/memory.copy
|
||||
local.get $1
|
||||
call $~lib/util/runtime/register
|
||||
)
|
||||
(func $~lib/util/runtime/discard (; 14 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
i32.const 2012
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 496
|
||||
i32.const 115
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 496
|
||||
i32.const 117
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start:number (; 15 ;) (type $FUNCSIG$v)
|
||||
(func $start:number (; 12 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 2016
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
i32.const 1968
|
||||
global.set $~lib/rt/index-stub/startOffset
|
||||
global.get $~lib/rt/index-stub/startOffset
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
global.get $number/a
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 552
|
||||
i32.const 496
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 7
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 56
|
||||
call $~lib/util/runtime/allocate
|
||||
call $~lib/rt/index-stub/__alloc
|
||||
local.tee $0
|
||||
call $~lib/util/number/dtoa_core
|
||||
local.set $1
|
||||
local.get $0
|
||||
local.get $1
|
||||
call $~lib/string/String#substring
|
||||
local.set $1
|
||||
local.get $0
|
||||
call $~lib/util/runtime/discard
|
||||
local.get $1
|
||||
i32.const 1856
|
||||
local.tee $1
|
||||
i32.const 28
|
||||
i32.lt_s
|
||||
if (result i32)
|
||||
local.get $0
|
||||
local.get $1
|
||||
call $~lib/string/String#substring
|
||||
else
|
||||
local.get $0
|
||||
end
|
||||
i32.const 1800
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 9
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1634,12 +1560,12 @@
|
||||
end
|
||||
i32.const 3
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 1880
|
||||
i32.const 1824
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 10
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1647,12 +1573,12 @@
|
||||
end
|
||||
i32.const -5
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 1904
|
||||
i32.const 1848
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1660,12 +1586,12 @@
|
||||
end
|
||||
i32.const 4
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 1928
|
||||
i32.const 1872
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1678,12 +1604,12 @@
|
||||
global.set $number/a
|
||||
local.get $0
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 1952
|
||||
i32.const 1896
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1696,36 +1622,36 @@
|
||||
global.set $number/a
|
||||
local.get $0
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 552
|
||||
i32.const 496
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 15
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1976
|
||||
i32.const 1976
|
||||
i32.const 1920
|
||||
i32.const 1920
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 16
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2000
|
||||
i32.const 2000
|
||||
i32.const 1944
|
||||
i32.const 1944
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 17
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1738,12 +1664,12 @@
|
||||
global.set $number/a
|
||||
local.get $0
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 552
|
||||
i32.const 496
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
@ -1756,22 +1682,22 @@
|
||||
global.set $number/a
|
||||
local.get $0
|
||||
call $~lib/util/number/itoa32
|
||||
i32.const 1952
|
||||
i32.const 1896
|
||||
call $~lib/string/String.__eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 576
|
||||
i32.const 520
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 16 ;) (type $FUNCSIG$v)
|
||||
(func $start (; 13 ;) (type $FUNCSIG$v)
|
||||
call $start:number
|
||||
)
|
||||
(func $null (; 17 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 14 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
178
tests/compiler/retain-release.optimized.wat
Normal file
178
tests/compiler/retain-release.optimized.wat
Normal file
@ -0,0 +1,178 @@
|
||||
(module
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00r\00e\00t\00a\00i\00n\00-\00r\00e\00l\00e\00a\00s\00e\00.\00t\00s")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $retain-release/receiveRef)
|
||||
(global $retain-release/glo (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/argc (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "returnRef" (func $retain-release/returnRef))
|
||||
(export "receiveRef" (func $retain-release/receiveRef))
|
||||
(export "receiveRefDrop" (func $retain-release/receiveRef))
|
||||
(export "receiveRefRetain" (func $retain-release/receiveRef))
|
||||
(export "takeRef" (func $retain-release/takeRef))
|
||||
(export "provideRef" (func $retain-release/receiveRef))
|
||||
(export "takeReturnRef" (func $retain-release/takeReturnRef))
|
||||
(export "provideReceiveRef" (func $retain-release/receiveRef))
|
||||
(export "newRef" (func $retain-release/newRef))
|
||||
(export "assignGlobal" (func $retain-release/assignGlobal))
|
||||
(export "assignField" (func $retain-release/assignField))
|
||||
(export "scopeBlock" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToUninitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToInitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToConditional" (func $retain-release/takeRef))
|
||||
(export "scopeTopLevelUninitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeTopLevelInitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeTopLevelConditional" (func $retain-release/takeRef))
|
||||
(export "scopeIf" (func $retain-release/takeRef))
|
||||
(export "scopeIfElse" (func $retain-release/takeRef))
|
||||
(export "scopeWhile" (func $retain-release/takeRef))
|
||||
(export "scopeDo" (func $retain-release/takeRef))
|
||||
(export "scopeFor" (func $retain-release/takeRef))
|
||||
(export "scopeBreak" (func $retain-release/takeRef))
|
||||
(export "scopeContinue" (func $retain-release/takeRef))
|
||||
(export "scopeThrow" (func $retain-release/scopeThrow))
|
||||
(export "scopeUnreachable" (func $retain-release/scopeUnreachable))
|
||||
(export "callInline" (func $retain-release/receiveRef))
|
||||
(export "provideRefInline" (func $retain-release/receiveRef))
|
||||
(export "receiveRefInline" (func $retain-release/receiveRef))
|
||||
(export "receiveRefInlineDrop" (func $retain-release/receiveRef))
|
||||
(export "provideRefIndirect" (func $retain-release/provideRefIndirect))
|
||||
(export "receiveRefIndirect" (func $retain-release/receiveRefIndirect))
|
||||
(export "receiveRefIndirectDrop" (func $retain-release/receiveRefIndirect))
|
||||
(start $start)
|
||||
(func $retain-release/returnRef (; 1 ;) (type $FUNCSIG$i) (result i32)
|
||||
i32.const 0
|
||||
)
|
||||
(func $retain-release/receiveRef (; 2 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/takeRef (; 3 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/takeReturnRef (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/index-stub/__alloc (; 5 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
global.get $~lib/rt/index-stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.tee $1
|
||||
i32.const 16
|
||||
i32.add
|
||||
i32.const -16
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $0
|
||||
i32.const 17
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store offset=12
|
||||
local.get $1
|
||||
)
|
||||
(func $retain-release/newRef (; 6 ;) (type $FUNCSIG$v)
|
||||
call $~lib/rt/index-stub/__alloc
|
||||
drop
|
||||
)
|
||||
(func $retain-release/assignGlobal (; 7 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
global.set $retain-release/glo
|
||||
)
|
||||
(func $retain-release/assignField (; 8 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
i32.load
|
||||
drop
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.store
|
||||
)
|
||||
(func $retain-release/scopeThrow (; 9 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 306
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeUnreachable (; 10 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $retain-release/provideRefIndirect (; 11 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 1
|
||||
global.set $~lib/argc
|
||||
i32.const 0
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$vi)
|
||||
)
|
||||
(func $retain-release/receiveRefIndirect (; 12 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 0
|
||||
global.set $~lib/argc
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$i)
|
||||
drop
|
||||
)
|
||||
(func $start (; 13 ;) (type $FUNCSIG$v)
|
||||
i32.const 64
|
||||
global.set $~lib/rt/index-stub/startOffset
|
||||
global.get $~lib/rt/index-stub/startOffset
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
)
|
||||
)
|
413
tests/compiler/retain-release.ts
Normal file
413
tests/compiler/retain-release.ts
Normal file
@ -0,0 +1,413 @@
|
||||
class Ref {}
|
||||
|
||||
export function returnRef(): Ref {
|
||||
|
||||
// Returning a reference must retain it because it could otherwise drop to
|
||||
// RC=0 before reaching the caller, for example if it was stored in a local
|
||||
// with RC=1 when this local becomes released at the end of the function. See
|
||||
// scope tests below.
|
||||
|
||||
return /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
}
|
||||
|
||||
export function receiveRef(): void {
|
||||
|
||||
// Receiving a reference from a call must keep track of it in a temporary
|
||||
// AUTORELEASE local because it has been pre-retained by the callee. This is
|
||||
// required because the reference could be immediately dropped and the caller
|
||||
// would otherwise not be able to release it properly.
|
||||
|
||||
!/* (TEMP = */ returnRef() /* ) */;
|
||||
// __release(TEMP)
|
||||
}
|
||||
|
||||
export function receiveRefDrop(): void {
|
||||
|
||||
// A straight forward optimization here is to detect immediate drops and skip
|
||||
// the temp local.
|
||||
|
||||
/*__release( */ returnRef() /* ) */;
|
||||
}
|
||||
|
||||
export function receiveRefRetain(): void {
|
||||
|
||||
// TODO: Another possible optimization is to detect that the target will
|
||||
// retain on its own, skip the temp local and mark the target as AUTORELEASE,
|
||||
// instead of doing:
|
||||
|
||||
var a = /* __retain(TEMP = */ returnRef() /* ) */;
|
||||
// __release(TEMP);
|
||||
// __release(a);
|
||||
}
|
||||
|
||||
export function takeRef(ref: Ref): void {
|
||||
|
||||
// Taking a reference as an argument must retain it while the body is
|
||||
// executing because reassigning the argument could otherwise drop to RC=0,
|
||||
// prematurely releasing the reference even though the caller still needs it.
|
||||
// This is the same as if the caller would retain it pre-call and release it
|
||||
// post-call, but from a code size perspective it makes more sense to make the
|
||||
// callee handle this instead of embedding runtime calls into every single
|
||||
// call. Downside is that the caller has more knowledge about the actual
|
||||
// arguments, like if these must actually be retained, while the upside is
|
||||
// that each function "just works" standalone.
|
||||
|
||||
// __retain(ref)
|
||||
// __release(ref)
|
||||
}
|
||||
|
||||
export function provideRef(): void {
|
||||
|
||||
// Providing a reference therefore doesn't do any retains or releases but
|
||||
// assumes that the callee will do this for us. The alternative of embedding
|
||||
// runtime calls into the call is discussed above, and also a valid strategy
|
||||
// for different reasons. It is likely that there are smart optimizations of
|
||||
// this case.
|
||||
|
||||
takeRef(changetype<Ref>(0));
|
||||
}
|
||||
|
||||
export function takeReturnRef(ref: Ref): Ref {
|
||||
|
||||
// Returning a reference provided as an argument must do all of the above but
|
||||
// can eliminate one set of retain/release by simply not releasing the
|
||||
// reference at the end of the function and skipping the retain on return.
|
||||
|
||||
// __retain(ref)
|
||||
return ref;
|
||||
|
||||
// What would otherwise be
|
||||
// /* (T = __retain( */ ref /* )), __release(ref), T */;
|
||||
}
|
||||
|
||||
export function provideReceiveRef(): void {
|
||||
|
||||
// Combined case of providing and receiving a reference, with no additional
|
||||
// logic compared to the base cases above.
|
||||
|
||||
!/* TEMP = */ takeReturnRef(changetype<Ref>(0));
|
||||
// __release(TEMP)
|
||||
}
|
||||
|
||||
export function newRef(): void {
|
||||
|
||||
// Allocating a reference must keep track of the allocation in a temporary
|
||||
// AUTORELEASE local because the allocation could be dropped immediately.
|
||||
// Similar to the receiveRef case, one possibile optimization here is to
|
||||
// detect immediate drops.
|
||||
|
||||
/* TEMP = */ new Ref();
|
||||
// __release(TEMP)
|
||||
}
|
||||
|
||||
var glo: Ref;
|
||||
|
||||
export function assignGlobal(): void {
|
||||
|
||||
// Assigning a reference to a global first retains it before releasing the
|
||||
// previously stored reference.
|
||||
|
||||
glo = /* __retainRelease( */ changetype<Ref>(0) /* , glo) */;
|
||||
}
|
||||
|
||||
class Target { fld: Ref; }
|
||||
|
||||
export function assignField(): void {
|
||||
|
||||
// Similar to the assignGlobal case, assigning a reference to a field first
|
||||
// retains it before releasing the previously stored reference.
|
||||
|
||||
changetype<Target>(0).fld = /* __retainRelease( */ changetype<Ref>(0) /* , fld) */;
|
||||
}
|
||||
|
||||
export function scopeBlock(): void {
|
||||
|
||||
// A scoped local must retain ownership of its reference for the same reasons
|
||||
// as in the takeRef case, because reassigning it could otherwise drop to RC=0
|
||||
// in a situation where the local holds a reference with RC=1, prematurely
|
||||
// releasing it even if the original reference is still in use.
|
||||
|
||||
{
|
||||
let $0 = /* __retain( */changetype<Ref>(0) /* } */;
|
||||
// __release($0)
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeBlockToUninitialized(): void {
|
||||
|
||||
// Top-level variables that have not yet been initialized do not have to
|
||||
// release `null` unless actually assigned a reference. Hence, such a var
|
||||
// doesn't have the AUTORELEASE property initially, but immediately takes it
|
||||
// as soon as it is assigned.
|
||||
|
||||
var $0: Ref; // uninitialized, so no AUTORELEASE yet
|
||||
{
|
||||
let $1 = /* __retain( */ changetype<Ref>(0) /* } */;
|
||||
$0 = /* __retain( */ $1 /* ) */;
|
||||
// __release($1)
|
||||
}
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function scopeBlockToInitialized(): void {
|
||||
|
||||
// Top-level variables that have been initialized must retain and release
|
||||
// their reference normally like in the takeRef and scopeBlock cases, for the
|
||||
// same reason of not prematurely dropping to RC=0 even though the original
|
||||
// reference is still in use.
|
||||
|
||||
var $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
{
|
||||
let $1 = /* __retain( */ changetype<Ref>(0) /* } */;
|
||||
$0 = /* __retainRelease( */ $1 /* , $0) */;
|
||||
// __release($1)
|
||||
}
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function scopeBlockToConditional(cond: bool): void {
|
||||
|
||||
// Top-level variables that are uninitialized, but may become initialized
|
||||
// conditionally, must even release `null` in the other case because the
|
||||
// compiler doesn't know the outcome of the condition statically.
|
||||
|
||||
var $0: Ref;
|
||||
if (cond) {
|
||||
$0 = /* __retain( */ changetype<Ref>(0) /* ) */; // now AUTORELEASE
|
||||
}
|
||||
{
|
||||
let $1 = /* __retain( */ changetype<Ref>(0) /* } */;
|
||||
$0 = /* __retainRelease( */ $1 /* , $0) */;
|
||||
// __release($1)
|
||||
}
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function scopeTopLevelUninitialized(): void {
|
||||
|
||||
// Isolated case of an uninitialized top-level variable that is never
|
||||
// initialized, and is thus never releasing `null`.
|
||||
|
||||
var $0: Ref;
|
||||
}
|
||||
|
||||
export function scopeTopLevelInitialized(): void {
|
||||
|
||||
// Isolated case of an initialized top-level variable that is never
|
||||
// reassigned. One possible optimization here is to detect this case and
|
||||
// eliminate the local with its retain/release altogether. Alternatively, a
|
||||
// warning could be omitted to inform the user that this var is unnecessary,
|
||||
// which I'd prefer because it hints the user at a portion of code that might
|
||||
// contain other errors.
|
||||
|
||||
var $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function scopeTopLevelConditional(cond: bool): void {
|
||||
|
||||
// Isolated case of an uninitialized top-level variable that is conditionally
|
||||
// assigned to, so that even `null` must be released at the end of the
|
||||
// function because the compiler doesn't know the outcome of the condition
|
||||
// statically.
|
||||
|
||||
var $0: Ref;
|
||||
if (cond) {
|
||||
$0 = /* __retain( */ changetype<Ref>(0) /* ) */; // now AUTORELEASE
|
||||
}
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function scopeIf(cond: bool): void {
|
||||
|
||||
// Validates that `if` scopes behave like blocks.
|
||||
|
||||
if (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeIfElse(cond: bool): void {
|
||||
|
||||
// Validates that `else` scopes behave like blocks.
|
||||
|
||||
if (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
} else {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeWhile(cond: bool): void {
|
||||
|
||||
// Validates that `while` scopes behave like blocks.
|
||||
|
||||
while (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeDo(cond: bool): void {
|
||||
|
||||
// Validates that `do` scopes behave like blocks.
|
||||
|
||||
do {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
} while (cond);
|
||||
}
|
||||
|
||||
export function scopeFor(cond: bool): void {
|
||||
|
||||
// Validates that `for` scopes behave like blocks.
|
||||
|
||||
for (; cond; ) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeBreak(cond: bool): void {
|
||||
|
||||
// Validates that `break` statements terminate flows so that no further
|
||||
// releases are performed afterwards.
|
||||
|
||||
while (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeContinue(cond: bool): void {
|
||||
|
||||
// Validates that `continue` statements terminate flows so that no further
|
||||
// releases are performed afterwards.
|
||||
|
||||
while (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeThrow(cond: bool): void {
|
||||
|
||||
// Validates that `throw` statements terminate flows so that no further
|
||||
// releases are performed afterwards.
|
||||
|
||||
while (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
throw new Error("error");
|
||||
}
|
||||
}
|
||||
|
||||
export function scopeUnreachable(cond: bool): void {
|
||||
|
||||
// Unreachable instructions are different in the sense that these are unsafe
|
||||
// compiler intrinsics that guarantee to have no unexpected side-effects,
|
||||
// hence don't terminate flows and result in an unreachable release after the
|
||||
// instruction (i.e. after the program has crashed).
|
||||
|
||||
while (cond) {
|
||||
let $0: Ref = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline
|
||||
function scopeInline(): void {
|
||||
|
||||
// Inlined function bodies should behave like normal scopes.
|
||||
|
||||
var $0 = /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
// __release($0)
|
||||
}
|
||||
|
||||
export function callInline(): void {
|
||||
|
||||
// Hosts scopeInline with no own logic.
|
||||
|
||||
scopeInline();
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline
|
||||
function takeRefInline(ref: Ref): void {
|
||||
|
||||
// The takeRef case but inline. Should retain and release while alive.
|
||||
|
||||
// __retain(ref)
|
||||
// __release(reF)
|
||||
}
|
||||
|
||||
export function provideRefInline(): void {
|
||||
|
||||
// The provideRef case but inline. Should do nothing to the arguments while
|
||||
// hosting the inlined retain and release.
|
||||
|
||||
takeRefInline(changetype<Ref>(0));
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline
|
||||
function returnRefInline(): Ref {
|
||||
|
||||
// The returnRef case but inline.
|
||||
|
||||
return /* __retain( */ changetype<Ref>(0) /* ) */;
|
||||
}
|
||||
|
||||
export function receiveRefInline(): void {
|
||||
|
||||
// The receiveRef case but inline.
|
||||
|
||||
!/* TEMP = */ returnRefInline();
|
||||
// __release(TEMP)
|
||||
}
|
||||
|
||||
export function receiveRefInlineDrop(): void {
|
||||
|
||||
// The receiveRefDrop case but inline.
|
||||
|
||||
/* __release( */ returnRefInline() /* ) */;
|
||||
|
||||
// TODO: Since we have access to both the block and the surrounding code here,
|
||||
// if we can prove that the last statement of the block does a retain, we can
|
||||
// eliminate it together with the receiver's release. Opt pass maybe?
|
||||
}
|
||||
|
||||
export function provideRefIndirect(fn: (ref: Ref) => void): void {
|
||||
|
||||
// An indirect call should behave just like a direct call, that is not insert
|
||||
// anything when providing a reference.
|
||||
|
||||
fn(changetype<Ref>(0));
|
||||
}
|
||||
|
||||
export function receiveRefIndirect(fn: () => Ref): void {
|
||||
|
||||
// An indirect call should behave just like a direct call, that is taking care
|
||||
// of release when receiving a reference.
|
||||
|
||||
!/* TEMP = */ fn();
|
||||
// __release(TEMP)
|
||||
}
|
||||
|
||||
export function receiveRefIndirectDrop(fn: () => Ref): void {
|
||||
|
||||
// An indirect call should behave just like a direct call, that is taking care
|
||||
// of release when receiving a reference.
|
||||
|
||||
/* __release( */ fn() /* ) */;
|
||||
}
|
||||
|
||||
// TODO: Optimize more immediate drops on alloc/call, like overloads, getters
|
||||
// and immediately assigning to a storage target.
|
550
tests/compiler/retain-release.untouched.wat
Normal file
550
tests/compiler/retain-release.untouched.wat
Normal file
@ -0,0 +1,550 @@
|
||||
(module
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00r\00e\00t\00a\00i\00n\00-\00r\00e\00l\00e\00a\00s\00e\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $retain-release/glo (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/index-stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/argc (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 60))
|
||||
(export "memory" (memory $0))
|
||||
(export "returnRef" (func $retain-release/returnRef))
|
||||
(export "receiveRef" (func $retain-release/receiveRef))
|
||||
(export "receiveRefDrop" (func $retain-release/receiveRefDrop))
|
||||
(export "receiveRefRetain" (func $retain-release/receiveRefRetain))
|
||||
(export "takeRef" (func $retain-release/takeRef))
|
||||
(export "provideRef" (func $retain-release/provideRef))
|
||||
(export "takeReturnRef" (func $retain-release/takeReturnRef))
|
||||
(export "provideReceiveRef" (func $retain-release/provideReceiveRef))
|
||||
(export "newRef" (func $retain-release/newRef))
|
||||
(export "assignGlobal" (func $retain-release/assignGlobal))
|
||||
(export "assignField" (func $retain-release/assignField))
|
||||
(export "scopeBlock" (func $retain-release/scopeBlock))
|
||||
(export "scopeBlockToUninitialized" (func $retain-release/scopeBlockToUninitialized))
|
||||
(export "scopeBlockToInitialized" (func $retain-release/scopeBlockToInitialized))
|
||||
(export "scopeBlockToConditional" (func $retain-release/scopeBlockToConditional))
|
||||
(export "scopeTopLevelUninitialized" (func $retain-release/scopeTopLevelUninitialized))
|
||||
(export "scopeTopLevelInitialized" (func $retain-release/scopeTopLevelInitialized))
|
||||
(export "scopeTopLevelConditional" (func $retain-release/scopeTopLevelConditional))
|
||||
(export "scopeIf" (func $retain-release/scopeIf))
|
||||
(export "scopeIfElse" (func $retain-release/scopeIfElse))
|
||||
(export "scopeWhile" (func $retain-release/scopeWhile))
|
||||
(export "scopeDo" (func $retain-release/scopeDo))
|
||||
(export "scopeFor" (func $retain-release/scopeFor))
|
||||
(export "scopeBreak" (func $retain-release/scopeBreak))
|
||||
(export "scopeContinue" (func $retain-release/scopeContinue))
|
||||
(export "scopeThrow" (func $retain-release/scopeThrow))
|
||||
(export "scopeUnreachable" (func $retain-release/scopeUnreachable))
|
||||
(export "callInline" (func $retain-release/callInline))
|
||||
(export "provideRefInline" (func $retain-release/provideRefInline))
|
||||
(export "receiveRefInline" (func $retain-release/receiveRefInline))
|
||||
(export "receiveRefInlineDrop" (func $retain-release/receiveRefInlineDrop))
|
||||
(export "provideRefIndirect" (func $retain-release/provideRefIndirect))
|
||||
(export "receiveRefIndirect" (func $retain-release/receiveRefIndirect))
|
||||
(export "receiveRefIndirectDrop" (func $retain-release/receiveRefIndirectDrop))
|
||||
(start $start)
|
||||
(func $~lib/rt/index-stub/__retain (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/returnRef (; 2 ;) (type $FUNCSIG$i) (result i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
)
|
||||
(func $~lib/rt/index-stub/__release (; 3 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/receiveRef (; 4 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
call $retain-release/returnRef
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefDrop (; 5 ;) (type $FUNCSIG$v)
|
||||
call $retain-release/returnRef
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefRetain (; 6 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
call $retain-release/returnRef
|
||||
local.tee $0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/takeRef (; 7 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/provideRef (; 8 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
call $retain-release/takeRef
|
||||
)
|
||||
(func $retain-release/takeReturnRef (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
drop
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/provideReceiveRef (; 10 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $retain-release/takeReturnRef
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $~lib/rt/index-stub/__alloc (; 11 ;) (type $FUNCSIG$iii) (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.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/rt/index-stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $5
|
||||
current_memory
|
||||
local.set $6
|
||||
local.get $5
|
||||
local.get $6
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $2
|
||||
i32.sub
|
||||
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 $6
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.tee $7
|
||||
local.get $4
|
||||
local.get $7
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $4
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $8
|
||||
local.get $8
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $8
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $retain-release/Ref#constructor (; 12 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 17
|
||||
call $~lib/rt/index-stub/__alloc
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/newRef (; 13 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $retain-release/Ref#constructor
|
||||
local.tee $0
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $~lib/rt/index-stub/__retainRelease (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/assignGlobal (; 15 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
global.get $retain-release/glo
|
||||
call $~lib/rt/index-stub/__retainRelease
|
||||
global.set $retain-release/glo
|
||||
)
|
||||
(func $retain-release/assignField (; 16 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
local.tee $0
|
||||
i32.const 0
|
||||
local.get $0
|
||||
i32.load
|
||||
call $~lib/rt/index-stub/__retainRelease
|
||||
i32.store
|
||||
)
|
||||
(func $retain-release/scopeBlock (; 17 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToUninitialized (; 18 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToInitialized (; 19 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__retainRelease
|
||||
local.set $0
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToConditional (; 20 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
end
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__retainRelease
|
||||
local.set $1
|
||||
local.get $2
|
||||
call $~lib/rt/index-stub/__release
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeTopLevelUninitialized (; 21 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/scopeTopLevelInitialized (; 22 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeTopLevelConditional (; 23 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
end
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/scopeIf (; 24 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeIfElse (; 25 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
else
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeWhile (; 26 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeDo (; 27 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
block
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
end
|
||||
local.get $0
|
||||
br_if $continue|0
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeFor (; 28 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
loop $repeat|0
|
||||
local.get $0
|
||||
i32.eqz
|
||||
br_if $break|0
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
br $repeat|0
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeBreak (; 29 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
br $break|0
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeContinue (; 30 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeThrow (; 31 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
block
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 306
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeUnreachable (; 32 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $1
|
||||
unreachable
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/callInline (; 33 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/provideRefInline (; 34 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefInline (; 35 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
block $retain-release/returnRefInline|inlined.0 (result i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
end
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefInlineDrop (; 36 ;) (type $FUNCSIG$v)
|
||||
block $retain-release/returnRefInline|inlined.1 (result i32)
|
||||
i32.const 0
|
||||
call $~lib/rt/index-stub/__retain
|
||||
end
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/provideRefIndirect (; 37 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 1
|
||||
global.set $~lib/argc
|
||||
i32.const 0
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$vi)
|
||||
)
|
||||
(func $retain-release/receiveRefIndirect (; 38 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
global.set $~lib/argc
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$i)
|
||||
local.tee $1
|
||||
end
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $1
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefIndirectDrop (; 39 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 0
|
||||
global.set $~lib/argc
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$i)
|
||||
call $~lib/rt/index-stub/__release
|
||||
)
|
||||
(func $start (; 40 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/builtins/HEAP_BASE
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/rt/index-stub/startOffset
|
||||
global.get $~lib/rt/index-stub/startOffset
|
||||
global.set $~lib/rt/index-stub/offset
|
||||
)
|
||||
(func $null (; 41 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -3,6 +3,6 @@
|
||||
"simd"
|
||||
],
|
||||
"asc_flags": [
|
||||
"--runtime trace"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
import { runtime, __runtime_id } from "runtime";
|
||||
/// <reference path="../../../std/assembly/rt/index.d.ts" />
|
||||
|
||||
import { idof } from "builtins";
|
||||
import { RTTIFlags } from "common/rtti";
|
||||
|
||||
function test<T>(flags: RTTIFlags): void {
|
||||
assert(
|
||||
runtime.flags(__runtime_id<T>())
|
||||
__typeinfo(idof<T>())
|
||||
==
|
||||
flags
|
||||
);
|
@ -1,6 +1,3 @@
|
||||
import { __runtime_id } from "runtime";
|
||||
import "../gc/_dummy";
|
||||
|
||||
class Animal {}
|
||||
class Cat extends Animal {}
|
||||
class BlackCat extends Cat {}
|
@ -1,331 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(")
|
||||
(data (i32.const 24) "~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 64) "\10\00\00\00\1e")
|
||||
(data (i32.const 80) "~\00l\00i\00b\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s")
|
||||
(data (i32.const 112) "\11\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00I\00\00\00\0e")
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "$.instanceof" (func $~lib/runtime/runtime.instanceof))
|
||||
(export "$.flags" (func $~lib/runtime/runtime.flags))
|
||||
(export "$.newObject" (func $~lib/runtime/runtime.newObject))
|
||||
(export "$.newString" (func $~lib/runtime/runtime.newString))
|
||||
(export "$.newArrayBuffer" (func $~lib/runtime/runtime.newArrayBuffer))
|
||||
(export "$.newArray" (func $~lib/runtime/runtime.newArray))
|
||||
(export "$.retain" (func $~lib/runtime/runtime.retain))
|
||||
(export "$.release" (func $~lib/runtime/runtime.retain))
|
||||
(export "$.collect" (func $~lib/runtime/runtime.collect))
|
||||
(start $start)
|
||||
(func $~lib/runtime/runtime.instanceof (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load
|
||||
local.tee $0
|
||||
if (result i32)
|
||||
local.get $0
|
||||
i32.const 112
|
||||
i32.load
|
||||
i32.le_u
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 112
|
||||
i32.add
|
||||
i32.load offset=4
|
||||
local.tee $0
|
||||
br_if $continue|0
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/runtime/runtime.flags (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
if (result i32)
|
||||
local.get $0
|
||||
i32.const 112
|
||||
i32.load
|
||||
i32.gt_u
|
||||
else
|
||||
i32.const 1
|
||||
end
|
||||
if (result i32)
|
||||
unreachable
|
||||
else
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 112
|
||||
i32.add
|
||||
i32.load
|
||||
end
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $0
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
local.tee $1
|
||||
i32.const -1520547049
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.add
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
i32.const 256
|
||||
i32.le_u
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.load
|
||||
i32.const -1520547049
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/runtime/runtime.newObject (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
block (result i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/allocate
|
||||
end
|
||||
local.get $1
|
||||
call $~lib/util/runtime/register
|
||||
)
|
||||
(func $~lib/runtime/runtime.newString (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.const 16
|
||||
call $~lib/runtime/runtime.newObject
|
||||
)
|
||||
(func $~lib/runtime/runtime.newArrayBuffer (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 15
|
||||
call $~lib/runtime/runtime.newObject
|
||||
)
|
||||
(func $~lib/runtime/runtime.newArray (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
local.get $0
|
||||
if (result i32)
|
||||
local.get $0
|
||||
i32.const 112
|
||||
i32.load
|
||||
i32.gt_u
|
||||
else
|
||||
i32.const 1
|
||||
end
|
||||
if (result i32)
|
||||
unreachable
|
||||
else
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 112
|
||||
i32.add
|
||||
i32.load
|
||||
end
|
||||
local.tee $3
|
||||
i32.const 16
|
||||
i32.div_u
|
||||
i32.const 31
|
||||
i32.and
|
||||
local.set $4
|
||||
local.get $1
|
||||
if (result i32)
|
||||
local.get $1
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
else
|
||||
i32.const 0
|
||||
call $~lib/runtime/runtime.newArrayBuffer
|
||||
local.set $1
|
||||
i32.const 0
|
||||
end
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 16
|
||||
call $~lib/runtime/runtime.newObject
|
||||
local.tee $0
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.store offset=4
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.store offset=8
|
||||
local.get $0
|
||||
local.get $2
|
||||
local.get $4
|
||||
i32.shr_u
|
||||
i32.store offset=12
|
||||
local.get $3
|
||||
i32.const 1024
|
||||
i32.and
|
||||
if
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
local.set $2
|
||||
loop $continue|0
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $1
|
||||
i32.load
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 80
|
||||
i32.const 97
|
||||
i32.const 15
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
i32.const 4
|
||||
i32.add
|
||||
local.set $1
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/runtime/runtime.retain (; 10 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/runtime/runtime.collect (; 11 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
i32.const 80
|
||||
i32.const 139
|
||||
i32.const 9
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
)
|
||||
(func $start (; 12 ;) (type $FUNCSIG$v)
|
||||
i32.const 256
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
)
|
||||
(func $null (; 13 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,392 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00(\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00u\00t\00i\00l\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 64) "\10\00\00\00\1e\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00")
|
||||
(data (i32.const 112) "\11\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00I\00\00\00\0e\00\00\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $~lib/util/runtime/HEADER_SIZE i32 (i32.const 16))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/util/runtime/HEADER_MAGIC i32 (i32.const -1520547049))
|
||||
(global $~lib/ASC_NO_ASSERT i32 (i32.const 0))
|
||||
(global $~lib/runtime/RTTI_BASE i32 (i32.const 112))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 256))
|
||||
(export "memory" (memory $0))
|
||||
(export "$.instanceof" (func $~lib/runtime/runtime.instanceof))
|
||||
(export "$.flags" (func $~lib/runtime/runtime.flags))
|
||||
(export "$.newObject" (func $~lib/runtime/runtime.newObject))
|
||||
(export "$.newString" (func $~lib/runtime/runtime.newString))
|
||||
(export "$.newArrayBuffer" (func $~lib/runtime/runtime.newArrayBuffer))
|
||||
(export "$.newArray" (func $~lib/runtime/runtime.newArray))
|
||||
(export "$.retain" (func $~lib/runtime/runtime.retain))
|
||||
(export "$.release" (func $~lib/runtime/runtime.release))
|
||||
(export "$.collect" (func $~lib/runtime/runtime.collect))
|
||||
(start $start)
|
||||
(func $~lib/runtime/runtime.instanceof (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
i32.load
|
||||
local.set $2
|
||||
global.get $~lib/runtime/RTTI_BASE
|
||||
local.set $3
|
||||
local.get $2
|
||||
if (result i32)
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.load
|
||||
i32.le_u
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $3
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.mul
|
||||
i32.add
|
||||
i32.load offset=4
|
||||
local.tee $2
|
||||
br_if $continue|0
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/runtime/runtime.flags (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
global.get $~lib/runtime/RTTI_BASE
|
||||
local.set $1
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if (result i32)
|
||||
i32.const 1
|
||||
else
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.load
|
||||
i32.gt_u
|
||||
end
|
||||
if (result i32)
|
||||
unreachable
|
||||
else
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.mul
|
||||
i32.add
|
||||
i32.load
|
||||
end
|
||||
)
|
||||
(func $~lib/util/runtime/adjust (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
i32.const 1
|
||||
i32.const 32
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.clz
|
||||
i32.sub
|
||||
i32.shl
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/util/runtime/allocate (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/adjust
|
||||
call $~lib/memory/memory.allocate
|
||||
local.set $1
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.store
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.store offset=4
|
||||
local.get $1
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.add
|
||||
)
|
||||
(func $~lib/util/runtime/register (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
local.get $0
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.gt_u
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 129
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load
|
||||
global.get $~lib/util/runtime/HEADER_MAGIC
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 131
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/runtime/runtime.newObject (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/util/runtime/allocate
|
||||
local.get $1
|
||||
call $~lib/util/runtime/register
|
||||
)
|
||||
(func $~lib/runtime/runtime.newString (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.const 16
|
||||
call $~lib/runtime/runtime.newObject
|
||||
)
|
||||
(func $~lib/runtime/runtime.newArrayBuffer (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 15
|
||||
call $~lib/runtime/runtime.newObject
|
||||
)
|
||||
(func $~lib/arraybuffer/ArrayBuffer#get:byteLength (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
global.get $~lib/util/runtime/HEADER_SIZE
|
||||
i32.sub
|
||||
i32.load offset=4
|
||||
)
|
||||
(func $~lib/runtime/runtime.newArray (; 12 ;) (type $FUNCSIG$iii) (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.get $0
|
||||
call $~lib/runtime/runtime.flags
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.div_u
|
||||
i32.const 31
|
||||
i32.and
|
||||
local.set $3
|
||||
local.get $1
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
local.tee $4
|
||||
call $~lib/runtime/runtime.newArrayBuffer
|
||||
local.set $1
|
||||
else
|
||||
local.get $1
|
||||
call $~lib/arraybuffer/ArrayBuffer#get:byteLength
|
||||
local.set $4
|
||||
end
|
||||
local.get $0
|
||||
i32.const 16
|
||||
call $~lib/runtime/runtime.newObject
|
||||
local.set $5
|
||||
local.get $5
|
||||
local.get $1
|
||||
i32.store
|
||||
local.get $5
|
||||
local.get $1
|
||||
i32.store offset=4
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.store offset=8
|
||||
local.get $5
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.shr_u
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
i32.const 1024
|
||||
i32.and
|
||||
if
|
||||
local.get $1
|
||||
local.set $6
|
||||
local.get $6
|
||||
local.get $4
|
||||
i32.add
|
||||
local.set $7
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $6
|
||||
local.get $7
|
||||
i32.lt_u
|
||||
if
|
||||
block
|
||||
local.get $6
|
||||
i32.load
|
||||
local.set $8
|
||||
local.get $8
|
||||
if
|
||||
i32.const 0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 80
|
||||
i32.const 97
|
||||
i32.const 15
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
local.get $6
|
||||
i32.const 4
|
||||
i32.add
|
||||
local.set $6
|
||||
end
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
)
|
||||
(func $~lib/runtime/runtime.retain (; 13 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/runtime/runtime.release (; 14 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/runtime/runtime.collect (; 15 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
i32.const 80
|
||||
i32.const 139
|
||||
i32.const 9
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
)
|
||||
(func $~lib/runtime/runtime#constructor (; 16 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
unreachable
|
||||
)
|
||||
(func $start (; 17 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
)
|
||||
(func $null (; 18 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime full"
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
2573
tests/compiler/runtime-full.untouched.wat
Normal file
2573
tests/compiler/runtime-full.untouched.wat
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime trace"
|
||||
"--runtime half"
|
||||
]
|
||||
}
|
8
tests/compiler/runtime-half.optimized.wat
Normal file
8
tests/compiler/runtime-half.optimized.wat
Normal file
@ -0,0 +1,8 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 0)
|
||||
(export "memory" (memory $0))
|
||||
(func $null (; 0 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
9
tests/compiler/runtime-half.untouched.wat
Normal file
9
tests/compiler/runtime-half.untouched.wat
Normal file
@ -0,0 +1,9 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 0)
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(export "memory" (memory $0))
|
||||
(func $null (; 0 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
"--runtime stub"
|
||||
]
|
||||
}
|
||||
}
|
366
tests/compiler/runtime-stub.optimized.wat
Normal file
366
tests/compiler/runtime-stub.optimized.wat
Normal file
@ -0,0 +1,366 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08")
|
||||
(global $stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $stub/offset (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "__alloc" (func $stub/__alloc))
|
||||
(export "__realloc" (func $stub/__realloc))
|
||||
(export "__free" (func $stub/__free))
|
||||
(export "__retain" (func $stub/__retain))
|
||||
(export "__release" (func $stub/__free))
|
||||
(export "__collect" (func $stub/__collect))
|
||||
(export "__instanceof" (func $~lib/rt/common/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/common/__typeinfo))
|
||||
(start $start)
|
||||
(func $stub/__alloc (; 0 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
local.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.tee $3
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const -16
|
||||
i32.and
|
||||
local.tee $2
|
||||
current_memory
|
||||
local.tee $4
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $5
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $2
|
||||
global.set $stub/offset
|
||||
local.get $3
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $2
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $3
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 1 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
local.tee $4
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
loop $continue|1
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $0
|
||||
local.get $1
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $1
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
loop $continue|2
|
||||
local.get $2
|
||||
if
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
local.tee $4
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
loop $continue|3
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
loop $continue|4
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
loop $continue|5
|
||||
local.get $2
|
||||
if
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $stub/__realloc (; 2 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.load offset=12
|
||||
local.tee $3
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.load offset=8
|
||||
call $stub/__alloc
|
||||
local.tee $1
|
||||
local.get $0
|
||||
local.get $3
|
||||
call $~lib/memory/memory.copy
|
||||
local.get $1
|
||||
local.set $0
|
||||
else
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store offset=12
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $stub/__free (; 3 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $stub/__retain (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $stub/__collect (; 5 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/common/__instanceof (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=8
|
||||
local.tee $0
|
||||
if (result i32)
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.load
|
||||
i32.le_u
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 8
|
||||
i32.add
|
||||
i32.load offset=4
|
||||
local.tee $0
|
||||
br_if $continue|0
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/rt/common/__typeinfo (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
if (result i32)
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.load
|
||||
i32.gt_u
|
||||
else
|
||||
i32.const 1
|
||||
end
|
||||
if (result i32)
|
||||
unreachable
|
||||
else
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 8
|
||||
i32.add
|
||||
i32.load
|
||||
end
|
||||
)
|
||||
(func $start (; 8 ;) (type $FUNCSIG$v)
|
||||
i32.const 144
|
||||
global.set $stub/startOffset
|
||||
global.get $stub/startOffset
|
||||
global.set $stub/offset
|
||||
)
|
||||
)
|
0
tests/compiler/runtime-stub.ts
Normal file
0
tests/compiler/runtime-stub.ts
Normal file
440
tests/compiler/runtime-stub.untouched.wat
Normal file
440
tests/compiler/runtime-stub.untouched.wat
Normal file
@ -0,0 +1,440 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/RTTI_BASE i32 (i32.const 8))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 144))
|
||||
(export "memory" (memory $0))
|
||||
(export "__alloc" (func $stub/__alloc))
|
||||
(export "__realloc" (func $stub/__realloc))
|
||||
(export "__free" (func $stub/__free))
|
||||
(export "__retain" (func $stub/__retain))
|
||||
(export "__release" (func $stub/__release))
|
||||
(export "__collect" (func $stub/__collect))
|
||||
(export "__instanceof" (func $~lib/rt/common/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/common/__typeinfo))
|
||||
(start $start)
|
||||
(func $stub/__alloc (; 0 ;) (type $FUNCSIG$iii) (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.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $5
|
||||
current_memory
|
||||
local.set $6
|
||||
local.get $5
|
||||
local.get $6
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $2
|
||||
i32.sub
|
||||
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 $6
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.tee $7
|
||||
local.get $4
|
||||
local.get $7
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $4
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
global.set $stub/offset
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $8
|
||||
local.get $8
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $8
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 1 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
block (result i32)
|
||||
local.get $0
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $5
|
||||
end
|
||||
block (result i32)
|
||||
local.get $1
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $5
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $0
|
||||
local.get $1
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $1
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
local.get $2
|
||||
if
|
||||
block (result i32)
|
||||
local.get $0
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $5
|
||||
end
|
||||
block (result i32)
|
||||
local.get $1
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $5
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|4
|
||||
loop $continue|4
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|5
|
||||
loop $continue|5
|
||||
local.get $2
|
||||
if
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $stub/__realloc (; 2 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load offset=12
|
||||
local.set $3
|
||||
local.get $1
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.load offset=8
|
||||
call $stub/__alloc
|
||||
local.set $4
|
||||
local.get $4
|
||||
local.get $0
|
||||
local.get $3
|
||||
call $~lib/memory/memory.copy
|
||||
local.get $4
|
||||
local.set $0
|
||||
else
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store offset=12
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $stub/__free (; 3 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $stub/__retain (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $stub/__release (; 5 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $stub/__collect (; 6 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/common/__instanceof (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=8
|
||||
local.set $2
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
local.set $3
|
||||
local.get $2
|
||||
if (result i32)
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.load
|
||||
i32.le_u
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $3
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.mul
|
||||
i32.add
|
||||
i32.load offset=4
|
||||
local.tee $2
|
||||
br_if $continue|0
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/rt/common/__typeinfo (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
local.set $1
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if (result i32)
|
||||
i32.const 1
|
||||
else
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.load
|
||||
i32.gt_u
|
||||
end
|
||||
if (result i32)
|
||||
unreachable
|
||||
else
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.mul
|
||||
i32.add
|
||||
i32.load
|
||||
end
|
||||
)
|
||||
(func $start (; 9 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/builtins/HEAP_BASE
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $stub/startOffset
|
||||
global.get $stub/startOffset
|
||||
global.set $stub/offset
|
||||
)
|
||||
(func $null (; 10 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,602 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$vii (func (param i32 i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00,")
|
||||
(data (i32.const 24) "s\00t\00d\00/\00a\00l\00l\00o\00c\00a\00t\00o\00r\00_\00a\00r\00e\00n\00a\00.\00t\00s")
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/ptr1 (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/ptr2 (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/i (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 1 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.tee $0
|
||||
i32.const 49
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
local.tee $1
|
||||
current_memory
|
||||
local.tee $2
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $2
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $1
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/memory/memory.fill (; 2 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
block $~lib/util/memory/memset|inlined.0
|
||||
local.get $0
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $0
|
||||
i32.const 42
|
||||
i32.add
|
||||
local.tee $1
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.add
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $0
|
||||
i32.const 2
|
||||
i32.add
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $1
|
||||
i32.const 2
|
||||
i32.sub
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $1
|
||||
i32.const 3
|
||||
i32.sub
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.add
|
||||
i32.const 18
|
||||
i32.store8
|
||||
local.get $1
|
||||
i32.const 4
|
||||
i32.sub
|
||||
i32.const 18
|
||||
i32.store8
|
||||
i32.const 42
|
||||
i32.const 0
|
||||
local.get $0
|
||||
i32.sub
|
||||
i32.const 3
|
||||
i32.and
|
||||
local.tee $1
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.add
|
||||
local.tee $0
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const -4
|
||||
i32.and
|
||||
local.tee $1
|
||||
local.get $0
|
||||
i32.add
|
||||
i32.const 4
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $1
|
||||
i32.const 8
|
||||
i32.le_u
|
||||
br_if $~lib/util/memory/memset|inlined.0
|
||||
local.get $0
|
||||
i32.const 4
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.add
|
||||
local.tee $2
|
||||
i32.const 12
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $1
|
||||
i32.const 24
|
||||
i32.le_u
|
||||
br_if $~lib/util/memory/memset|inlined.0
|
||||
local.get $0
|
||||
i32.const 12
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 20
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 24
|
||||
i32.add
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.add
|
||||
local.tee $2
|
||||
i32.const 28
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 24
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 20
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.const 303174162
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 4
|
||||
i32.and
|
||||
i32.const 24
|
||||
i32.add
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.sub
|
||||
local.set $1
|
||||
loop $continue|0
|
||||
local.get $1
|
||||
i32.const 32
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $0
|
||||
i64.const 1302123111085380114
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
i64.const 1302123111085380114
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
i64.const 1302123111085380114
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 24
|
||||
i32.add
|
||||
i64.const 1302123111085380114
|
||||
i64.store
|
||||
local.get $1
|
||||
i32.const 32
|
||||
i32.sub
|
||||
local.set $1
|
||||
local.get $0
|
||||
i32.const 32
|
||||
i32.add
|
||||
local.set $0
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 3 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
i32.const 42
|
||||
local.set $2
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
local.tee $4
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
loop $continue|1
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $0
|
||||
local.get $1
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $1
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
loop $continue|2
|
||||
local.get $2
|
||||
if
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
local.tee $4
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
loop $continue|3
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $2
|
||||
i32.eqz
|
||||
br_if $~lib/util/memory/memmove|inlined.0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
loop $continue|4
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
loop $continue|5
|
||||
local.get $2
|
||||
if
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
local.get $0
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $start:std/allocator_arena (; 4 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
i32.const 72
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
global.set $std/allocator_arena/ptr1
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
global.set $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/ptr2
|
||||
i32.eq
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 7
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/ptr1
|
||||
call $~lib/memory/memory.fill
|
||||
i32.const 0
|
||||
global.set $std/allocator_arena/i
|
||||
loop $repeat|0
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 42
|
||||
i32.lt_u
|
||||
if
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/i
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.const 18
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 12
|
||||
i32.const 27
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
else
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $std/allocator_arena/i
|
||||
br $repeat|0
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
global.get $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/ptr1
|
||||
call $~lib/memory/memory.copy
|
||||
i32.const 0
|
||||
global.set $std/allocator_arena/i
|
||||
loop $repeat|1
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 42
|
||||
i32.lt_u
|
||||
if
|
||||
global.get $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/i
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.const 18
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 16
|
||||
i32.const 27
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
else
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $std/allocator_arena/i
|
||||
br $repeat|1
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
block $~lib/util/memory/memcmp|inlined.0 (result i32)
|
||||
i32.const 42
|
||||
local.set $0
|
||||
i32.const 0
|
||||
global.get $std/allocator_arena/ptr2
|
||||
local.tee $1
|
||||
global.get $std/allocator_arena/ptr1
|
||||
local.tee $2
|
||||
i32.eq
|
||||
br_if $~lib/util/memory/memcmp|inlined.0
|
||||
drop
|
||||
loop $continue|2
|
||||
local.get $0
|
||||
if (result i32)
|
||||
local.get $2
|
||||
i32.load8_u
|
||||
local.get $1
|
||||
i32.load8_u
|
||||
i32.eq
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
local.get $0
|
||||
if (result i32)
|
||||
local.get $2
|
||||
i32.load8_u
|
||||
local.get $1
|
||||
i32.load8_u
|
||||
i32.sub
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
end
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 18
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
global.set $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/ptr1
|
||||
i32.const 72
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 25
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 5 ;) (type $FUNCSIG$v)
|
||||
call $start:std/allocator_arena
|
||||
)
|
||||
(func $null (; 6 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
@ -1,25 +0,0 @@
|
||||
import "allocator/arena";
|
||||
|
||||
const size: usize = 42;
|
||||
var ptr1: usize = memory.allocate(size);
|
||||
var ptr2: usize = memory.allocate(size);
|
||||
|
||||
assert(ptr1 != ptr2);
|
||||
|
||||
memory.fill(ptr1, 0x12, size);
|
||||
|
||||
var i: usize;
|
||||
for (i = 0; i < size; ++i) assert(load<u8>(ptr1 + i) == 0x12);
|
||||
|
||||
memory.copy(ptr2, ptr1, size);
|
||||
|
||||
for (i = 0; i < size; ++i) assert(load<u8>(ptr2 + i) == 0x12);
|
||||
|
||||
assert(memory.compare(ptr1, ptr2, size) == 0);
|
||||
|
||||
memory.free(ptr1);
|
||||
memory.free(ptr2);
|
||||
|
||||
memory.reset();
|
||||
ptr1 = memory.allocate(size);
|
||||
assert(ptr1 == ((HEAP_BASE + 7) & ~7));
|
@ -1,803 +0,0 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00,\00\00\00\00\00\00\00\00\00\00\00s\00t\00d\00/\00a\00l\00l\00o\00c\00a\00t\00o\00r\00_\00a\00r\00e\00n\00a\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $std/allocator_arena/size i32 (i32.const 42))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/ptr1 (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/ptr2 (mut i32) (i32.const 0))
|
||||
(global $std/allocator_arena/i (mut i32) (i32.const 0))
|
||||
(global $~lib/memory/HEAP_BASE i32 (i32.const 68))
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $~lib/allocator/arena/__mem_allocate (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
local.get $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/allocator/arena/offset
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
local.tee $2
|
||||
i32.const 1
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $4
|
||||
current_memory
|
||||
local.set $5
|
||||
local.get $4
|
||||
local.get $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $4
|
||||
local.get $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $2
|
||||
local.get $5
|
||||
local.tee $3
|
||||
local.get $2
|
||||
local.tee $6
|
||||
local.get $3
|
||||
local.get $6
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $3
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $4
|
||||
global.set $~lib/allocator/arena/offset
|
||||
local.get $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/memory/memory.fill (; 3 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i64)
|
||||
block $~lib/util/memory/memset|inlined.0
|
||||
local.get $2
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 2
|
||||
i32.le_u
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $0
|
||||
i32.const 2
|
||||
i32.add
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 2
|
||||
i32.sub
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 3
|
||||
i32.sub
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 6
|
||||
i32.le_u
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.add
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 4
|
||||
i32.sub
|
||||
local.get $1
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.le_u
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
i32.const 0
|
||||
local.get $0
|
||||
i32.sub
|
||||
i32.const 3
|
||||
i32.and
|
||||
local.set $5
|
||||
local.get $0
|
||||
local.get $5
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $2
|
||||
local.get $5
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.const -4
|
||||
i32.and
|
||||
local.set $2
|
||||
i32.const -1
|
||||
i32.const 255
|
||||
i32.div_u
|
||||
local.get $1
|
||||
i32.const 255
|
||||
i32.and
|
||||
i32.mul
|
||||
local.set $4
|
||||
local.get $0
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 4
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.le_u
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
i32.const 4
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 12
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $2
|
||||
i32.const 24
|
||||
i32.le_u
|
||||
if
|
||||
br $~lib/util/memory/memset|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
i32.const 12
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 20
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
i32.const 24
|
||||
i32.add
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 28
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 24
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 20
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.get $4
|
||||
i32.store
|
||||
i32.const 24
|
||||
local.get $0
|
||||
i32.const 4
|
||||
i32.and
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $0
|
||||
local.get $5
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $2
|
||||
local.get $5
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $4
|
||||
i64.extend_i32_u
|
||||
local.get $4
|
||||
i64.extend_i32_u
|
||||
i64.const 32
|
||||
i64.shl
|
||||
i64.or
|
||||
local.set $6
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $2
|
||||
i32.const 32
|
||||
i32.ge_u
|
||||
if
|
||||
block
|
||||
local.get $0
|
||||
local.get $6
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.get $6
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.get $6
|
||||
i64.store
|
||||
local.get $0
|
||||
i32.const 24
|
||||
i32.add
|
||||
local.get $6
|
||||
i64.store
|
||||
local.get $2
|
||||
i32.const 32
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 32
|
||||
i32.add
|
||||
local.set $0
|
||||
end
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 4 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
block
|
||||
local.get $2
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
block (result i32)
|
||||
local.get $0
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $5
|
||||
end
|
||||
block (result i32)
|
||||
local.get $1
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $5
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
end
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
block
|
||||
local.get $0
|
||||
local.get $1
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $1
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $1
|
||||
end
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
local.get $2
|
||||
if
|
||||
block
|
||||
block (result i32)
|
||||
local.get $0
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $0
|
||||
local.get $5
|
||||
end
|
||||
block (result i32)
|
||||
local.get $1
|
||||
local.tee $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $1
|
||||
local.get $5
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $2
|
||||
end
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $1
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $0
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
block
|
||||
local.get $2
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
end
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|4
|
||||
loop $continue|4
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
block
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
end
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|5
|
||||
loop $continue|5
|
||||
local.get $2
|
||||
if
|
||||
local.get $0
|
||||
local.get $2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $2
|
||||
i32.add
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_free (; 5 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/memory/memory.free (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
call $~lib/allocator/arena/__mem_free
|
||||
)
|
||||
(func $~lib/allocator/arena/__mem_reset (; 7 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
)
|
||||
(func $~lib/memory/memory.reset (; 8 ;) (type $FUNCSIG$v)
|
||||
call $~lib/allocator/arena/__mem_reset
|
||||
)
|
||||
(func $start:std/allocator_arena (; 9 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/allocator/arena/startOffset
|
||||
global.get $~lib/allocator/arena/startOffset
|
||||
global.set $~lib/allocator/arena/offset
|
||||
global.get $std/allocator_arena/size
|
||||
call $~lib/memory/memory.allocate
|
||||
global.set $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/size
|
||||
call $~lib/memory/memory.allocate
|
||||
global.set $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/ptr2
|
||||
i32.ne
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 7
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/ptr1
|
||||
i32.const 18
|
||||
global.get $std/allocator_arena/size
|
||||
call $~lib/memory/memory.fill
|
||||
block $break|0
|
||||
i32.const 0
|
||||
global.set $std/allocator_arena/i
|
||||
loop $repeat|0
|
||||
global.get $std/allocator_arena/i
|
||||
global.get $std/allocator_arena/size
|
||||
i32.lt_u
|
||||
i32.eqz
|
||||
br_if $break|0
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/i
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.const 18
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 12
|
||||
i32.const 27
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $std/allocator_arena/i
|
||||
br $repeat|0
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/size
|
||||
call $~lib/memory/memory.copy
|
||||
block $break|1
|
||||
i32.const 0
|
||||
global.set $std/allocator_arena/i
|
||||
loop $repeat|1
|
||||
global.get $std/allocator_arena/i
|
||||
global.get $std/allocator_arena/size
|
||||
i32.lt_u
|
||||
i32.eqz
|
||||
br_if $break|1
|
||||
global.get $std/allocator_arena/ptr2
|
||||
global.get $std/allocator_arena/i
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.const 18
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 16
|
||||
i32.const 27
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/i
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $std/allocator_arena/i
|
||||
br $repeat|1
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
block $~lib/memory/memory.compare|inlined.0 (result i32)
|
||||
global.get $std/allocator_arena/ptr1
|
||||
local.set $2
|
||||
global.get $std/allocator_arena/ptr2
|
||||
local.set $1
|
||||
global.get $std/allocator_arena/size
|
||||
local.set $0
|
||||
block $~lib/util/memory/memcmp|inlined.0 (result i32)
|
||||
local.get $2
|
||||
local.set $5
|
||||
local.get $1
|
||||
local.set $4
|
||||
local.get $0
|
||||
local.set $3
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.eq
|
||||
if
|
||||
i32.const 0
|
||||
br $~lib/util/memory/memcmp|inlined.0
|
||||
end
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
local.get $3
|
||||
i32.const 0
|
||||
i32.ne
|
||||
if (result i32)
|
||||
local.get $5
|
||||
i32.load8_u
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.eq
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
block
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $3
|
||||
local.get $5
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $4
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $4
|
||||
end
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $3
|
||||
if (result i32)
|
||||
local.get $5
|
||||
i32.load8_u
|
||||
local.get $4
|
||||
i32.load8_u
|
||||
i32.sub
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 18
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $std/allocator_arena/ptr1
|
||||
call $~lib/memory/memory.free
|
||||
global.get $std/allocator_arena/ptr2
|
||||
call $~lib/memory/memory.free
|
||||
call $~lib/memory/memory.reset
|
||||
global.get $std/allocator_arena/size
|
||||
call $~lib/memory/memory.allocate
|
||||
global.set $std/allocator_arena/ptr1
|
||||
global.get $std/allocator_arena/ptr1
|
||||
global.get $~lib/memory/HEAP_BASE
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 25
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 10 ;) (type $FUNCSIG$v)
|
||||
call $start:std/allocator_arena
|
||||
)
|
||||
(func $null (; 11 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
import "allocator/tlsf";
|
||||
import { HEADER, HEADER_SIZE, HEADER_MAGIC, adjust, allocate, reallocate, discard, register } from "util/runtime";
|
||||
import { runtime, __runtime_id } from "runtime";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@start
|
||||
export function main(): void {}
|
||||
|
||||
var register_ref: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
function __ref_register(ref: usize): void {
|
||||
register_ref = ref;
|
||||
}
|
||||
|
||||
var link_ref: usize = 0;
|
||||
var link_parentRef: usize = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
function __ref_link(ref: usize, parentRef: usize): void {
|
||||
link_ref = ref;
|
||||
link_parentRef = parentRef;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
function __ref_unlink(ref: usize, parentRef: usize): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
function __ref_collect(): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
function __ref_mark(ref: usize): void {
|
||||
}
|
||||
|
||||
class A {}
|
||||
class B {}
|
||||
assert(__runtime_id<A>() != __runtime_id<B>());
|
||||
|
||||
function isPowerOf2(x: i32): bool {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
assert(adjust(0) > 0);
|
||||
for (let i = 0; i < 9000; ++i) {
|
||||
assert(isPowerOf2(adjust(i)));
|
||||
}
|
||||
|
||||
var barrier1 = adjust(0);
|
||||
var barrier2 = barrier1 + 1;
|
||||
while (adjust(barrier2 + 1) == adjust(barrier2)) ++barrier2;
|
||||
var barrier3 = barrier2 + 1;
|
||||
while (adjust(barrier3 + 1) == adjust(barrier3)) ++barrier3;
|
||||
|
||||
trace("barrier1", 1, barrier1);
|
||||
trace("barrier2", 1, barrier2);
|
||||
trace("barrier3", 1, barrier3);
|
||||
|
||||
var ref1 = allocate(1);
|
||||
var header1 = changetype<HEADER>(ref1 - HEADER_SIZE);
|
||||
assert(header1.classId == HEADER_MAGIC);
|
||||
assert(header1.payloadSize == 1);
|
||||
assert(ref1 == reallocate(ref1, barrier1)); // same segment
|
||||
assert(header1.payloadSize == barrier1);
|
||||
var ref2 = reallocate(ref1, barrier2);
|
||||
assert(ref1 != ref2); // moves
|
||||
var header2 = changetype<HEADER>(ref2 - HEADER_SIZE);
|
||||
assert(header2.payloadSize == barrier2);
|
||||
discard(ref2);
|
||||
var ref3 = allocate(barrier2);
|
||||
assert(ref1 == ref3); // reuses space of ref1 (free'd in realloc), ref2 (explicitly free'd)
|
||||
|
||||
var ref4 = allocate(barrier1);
|
||||
register(ref4, __runtime_id<A>()); // should call __gc_register
|
||||
assert(register_ref == ref4);
|
||||
var header4 = changetype<HEADER>(register_ref - HEADER_SIZE);
|
||||
assert(header4.classId == __runtime_id<A>());
|
||||
assert(header4.payloadSize == barrier1);
|
||||
|
||||
var ref5 = allocate(10);
|
||||
assert(changetype<ArrayBuffer>(ref5).byteLength == 10);
|
||||
assert(changetype<String>(ref5).length == 5);
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
/// <reference path="../../../std/assembly/rt/index.d.ts" />
|
||||
|
||||
var str = "𐐷hi𤭢"; // -> f0 90 90 b7 68 69 f0 a4 ad a2 00
|
||||
|
||||
var len = str.lengthUTF8;
|
||||
@ -25,4 +27,4 @@ assert(String.fromUTF8(ptr + 4, 2) == "hi");
|
||||
assert(String.fromUTF8(ptr + 6, 4) == "𤭢");
|
||||
assert(String.fromUTF8(ptr + 10, 1) == "\0");
|
||||
|
||||
memory.free(ptr);
|
||||
__free(ptr);
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"asc_flags": [
|
||||
"--runtime arena"
|
||||
"--runtime none"
|
||||
]
|
||||
}
|
@ -193,9 +193,9 @@ assert(sub32.byteLength == 3 * sizeof<i32>());
|
||||
assert(isInt32ArrayEqual(sub32, <i32[]>[0, 0, 0]));
|
||||
assert(isInt32ArrayEqual(arr32, <i32[]>[1, 0, 0, 0, 2]));
|
||||
|
||||
import { MAX_BYTELENGTH } from "util/runtime";
|
||||
import { BLOCK_OVERHEAD } from "rt/common";
|
||||
|
||||
const MAX_F64LENGTH = <u32>MAX_BYTELENGTH >> alignof<f64>();
|
||||
const MAX_F64LENGTH = <u32>BLOCK_OVERHEAD >> alignof<f64>();
|
||||
new Float64Array(MAX_F64LENGTH); // 1GB
|
||||
// new Float64Array(MAX_F64 + 1); // throws
|
||||
|
||||
|
Reference in New Issue
Block a user