unify, stub impl

This commit is contained in:
dcode 2019-04-18 12:53:48 +02:00
parent 8216cf3361
commit 18c3f0c555
15 changed files with 346 additions and 141 deletions

View File

@ -4,3 +4,30 @@ The AssemblyScript Runtime
The runtime provides the functionality necessary to dynamically allocate and deallocate memory of objects, arrays and buffers, as well as keep track of references that are no longer used.
It is based on [the TLSF memory manager](./tlsf.ts) and [a pure reference counting garbage collector](./pure.ts).
Interface
---------
* **__rt_allocate**(size: `usize`, id: `u32` = 0): `usize`<br />
Dynamically allocates a chunk of memory of at least the specified size and returns its address.
Alignment is guaranteed to be 16 bytes to fit up to v128 values naturally.
* **__rt_free**(ref: `usize`): `void`<br />
Frees a dynamically allocated chunk of memory by its address.
* **__rt_retain**(ref: `usize`): `void`<br />
Retains a reference.
* **__rt_release**(ref: `usize`): `void`<br />
Releases a reference.
* **__rt_collect**(): `void`<br />
Forces a full garbage collection cycle.
* **__rt_typeinfo**(id: `u32`): `void`<br />
Obtains the runtime type information for objects of the kind represented by the specified id.
Stub
----
The fully functional yet minimal [stub implementation](./stub.ts) provides dynamic memory allocation only but doesn't include sophisticated support to deallocate objects. Useful for prototyping or very short-lived programs with hardly any memory footprint.

View File

@ -11,3 +11,29 @@
// @ts-ignore: decorator
@inline export const DEBUG = true;
/** Common block structure. */
@unmanaged export class CommonBlock {
/** Memory manager info. */
mmInfo: usize; // WASM64 might need adaption
/** Garbage collector info. */
gcInfo: u32;
/** Runtime class id. */
rtId: u32;
/** Runtime object size. */
rtSize: u32;
}
/////////////////////////////////// Type information interface ////////////////////////////////////
import { RTTI_BASE } from "../runtime";
import { RTTIData } from "../common/rtti";
// @ts-ignore: decorator
@global @unsafe
function __rt_typeinfo(id: u32): u32 {
var ptr: usize = RTTI_BASE;
return !id || id > load<u32>(ptr)
? unreachable()
: changetype<RTTIData>(ptr + id * offsetof<RTTIData>()).flags;
}

View File

@ -1,52 +1,56 @@
import { AL_MASK, DEBUG } from "./common";
import { ROOT, Block, BLOCK_OVERHEAD, initializeRoot, allocateBlock, reallocateBlock, freeBlock } from "./tlsf";
import { increment, decrement, collectCycles } from "./pure";
//////////////////////////////////// Memory manager interface /////////////////////////////////////
import { ROOT, Block, BLOCK_OVERHEAD, initializeRoot, allocateBlock, reallocateBlock, freeBlock } from "./tlsf";
// @ts-ignore: decorator
@global @unsafe
function __mm_allocate(size: usize): usize {
function __rt_allocate(size: usize, id: u32): usize {
var root = ROOT;
if (!root) {
initializeRoot();
root = ROOT;
}
return changetype<usize>(allocateBlock(root, size)) + BLOCK_OVERHEAD;
var block = allocateBlock(root, size);
block.rtId = id;
return changetype<usize>(block) + BLOCK_OVERHEAD;
}
// @ts-ignore: decorator
@global @unsafe
function __mm_reallocate(data: usize, size: usize): usize {
function __rt_reallocate(ref: usize, size: usize): usize {
if (DEBUG) assert(ROOT); // must be initialized
assert(data != 0 && !(data & AL_MASK)); // must exist and be aligned
return changetype<usize>(reallocateBlock(ROOT, changetype<Block>(data - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD;
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
return changetype<usize>(reallocateBlock(ROOT, changetype<Block>(ref - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD;
}
// @ts-ignore: decorator
@global @unsafe
function __mm_free(data: usize): void {
function __rt_free(ref: usize): void {
if (DEBUG) assert(ROOT); // must be initialized
assert(data != 0 && !(data & AL_MASK)); // must exist and be aligned
freeBlock(ROOT, changetype<Block>(data - BLOCK_OVERHEAD));
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
freeBlock(ROOT, changetype<Block>(ref - BLOCK_OVERHEAD));
}
/////////////////////////////////// Garbage collector interface ///////////////////////////////////
import { increment, decrement, collectCycles } from "./pure";
// @ts-ignore: decorator
@global @unsafe
function __gc_retain(ref: usize): void {
function __rt_retain(ref: usize): void {
if (ref) increment(changetype<Block>(ref - BLOCK_OVERHEAD));
}
// @ts-ignore: decorator
@global @unsafe
function __gc_release(ref: usize): void {
function __rt_release(ref: usize): void {
if (ref) decrement(changetype<Block>(ref - BLOCK_OVERHEAD));
}
// @ts-ignore: decorator
@global @unsafe
function __gc_collect(): void {
function __rt_collect(): void {
collectCycles();
}

77
std/assembly/rt/stub.ts Normal file
View File

@ -0,0 +1,77 @@
import { AL_MASK, CommonBlock } from "./common";
// @ts-ignore: decorator
@inline
const BLOCK_OVERHEAD = offsetof<CommonBlock>();
// @ts-ignore: decorator
@inline
const BLOCK_MAXSIZE: usize = (1 << 30) - BLOCK_OVERHEAD; // match TLSF
// @ts-ignore: decorator
@lazy
var startOffset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
// @ts-ignore: decorator
@lazy
var offset: usize = startOffset;
//////////////////////////////////// Memory manager interface /////////////////////////////////////
// @ts-ignore: decorator
@unsafe @global
function __rt_allocate(size: usize, id: u32): usize {
if (size > BLOCK_MAXSIZE) unreachable();
var ptr = offset + BLOCK_OVERHEAD;
var newPtr = (ptr + max<usize>(size, 1) + AL_MASK) & ~AL_MASK;
var pagesBefore = memory.size();
if (newPtr > <usize>pagesBefore << 16) {
let pagesNeeded = ((newPtr - ptr + 0xffff) & ~0xffff) >>> 16;
let pagesWanted = max(pagesBefore, pagesNeeded); // double memory
if (memory.grow(pagesWanted) < 0) {
if (memory.grow(pagesNeeded) < 0) unreachable(); // out of memory
}
}
offset = newPtr;
var block = changetype<CommonBlock>(ptr - BLOCK_OVERHEAD);
block.rtId = id;
block.rtSize = size;
return ptr;
}
// @ts-ignore: decorator
@unsafe @global
function __rt_reallocate(ref: usize, size: usize): usize {
var block = changetype<CommonBlock>(ref - BLOCK_OVERHEAD);
var newRef = __rt_allocate(size, block.rtId);
memory.copy(newRef, ref, block.rtSize);
return newRef;
}
// @ts-ignore: decorator
@unsafe @global
function __rt_free(ref: usize): void {
}
// @ts-ignore: decorator
@unsafe @global
function __rt_reset(): void { // special
offset = startOffset;
}
/////////////////////////////////// Garbage collector interface ///////////////////////////////////
// @ts-ignore: decorator
@global @unsafe
function __rt_retain(ref: usize): void {
}
// @ts-ignore: decorator
@global @unsafe
function __rt_release(ref: usize): void {
}
// @ts-ignore: decorator
@global @unsafe
function __rt_collect(): void {
}

View File

@ -1,4 +1,4 @@
import { AL_BITS, AL_SIZE, AL_MASK, DEBUG } from "./common";
import { AL_BITS, AL_SIZE, AL_MASK, DEBUG, CommonBlock } from "./common";
/////////////////////// The TLSF (Two-Level Segregate Fit) memory allocator ///////////////////////
// see: http://www.gii.upv.es/tlsf/
@ -69,16 +69,7 @@ import { AL_BITS, AL_SIZE, AL_MASK, DEBUG } from "./common";
// │ if free: back ▲ │ ◄─┘
// └───────────────────────────────────────────────────────────────┘ payload ┘ >= MIN SIZE
// F: FREE, L: LEFTFREE
@unmanaged export class Block {
/** Memory manager info. */
mmInfo: usize; // WASM64 might need adaption
/** Garbage collector info. */
gcInfo: u32;
/** Runtime class id. */
rtId: u32;
/** Runtime object size. */
rtSize: u32;
@unmanaged export class Block extends CommonBlock {
/** Previous free block, if any. Only valid if free, otherwise part of payload. */
prev: Block | null;

View File

@ -3,10 +3,10 @@ import { memory as builtin_memory } from "memory";
export namespace memory {
export function allocate(size: usize): usize {
return __mm_allocate(size);
return __rt_allocate(size, 0);
}
export function free(ptr: usize): void {
__mm_free(ptr);
__rt_free(ptr);
}
export function fill(dst: usize, c: u8, n: usize): void {
builtin_memory.fill(dst, c, n);

View File

@ -1,8 +1,8 @@
(module
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$v (func))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$iii (func (param i32 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)))
@ -497,7 +497,7 @@
if
i32.const 0
i32.const 24
i32.const 436
i32.const 427
i32.const 29
call $~lib/builtins/abort
unreachable
@ -758,7 +758,7 @@
call $~lib/rt/tlsf/prepareBlock
local.get $2
)
(func $assembly/index/memory.allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/rt/index/__rt_allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
global.get $~lib/rt/tlsf/ROOT
local.tee $1
@ -770,10 +770,18 @@
end
local.get $0
call $~lib/rt/tlsf/allocateBlock
local.tee $0
i32.const 0
i32.store offset=8
local.get $0
i32.const 16
i32.add
)
(func $assembly/index/memory.free (; 11 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $assembly/index/memory.allocate (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
call $~lib/rt/index/__rt_allocate
)
(func $assembly/index/memory.free (; 12 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
i32.const 16
i32.sub
@ -787,7 +795,7 @@
local.get $0
call $~lib/rt/tlsf/insertBlock
)
(func $~lib/memory/memory.fill (; 12 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/memory/memory.fill (; 13 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i64)
(local $4 i32)
block $~lib/util/memory/memset|inlined.0
@ -1017,13 +1025,13 @@
end
end
)
(func $assembly/index/memory.fill (; 13 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $assembly/index/memory.fill (; 14 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0
local.get $1
local.get $2
call $~lib/memory/memory.fill
)
(func $null (; 14 ;) (type $FUNCSIG$v)
(func $null (; 15 ;) (type $FUNCSIG$v)
nop
)
)

View File

@ -1,10 +1,10 @@
(module
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$v (func))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$viii (func (param i32 i32 i32)))
(type $FUNCSIG$vi (func (param i32)))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
@ -41,7 +41,7 @@
if
i32.const 0
i32.const 24
i32.const 265
i32.const 256
i32.const 13
call $~lib/builtins/abort
unreachable
@ -66,7 +66,7 @@
if
i32.const 0
i32.const 24
i32.const 267
i32.const 258
i32.const 13
call $~lib/builtins/abort
unreachable
@ -118,7 +118,7 @@
if
i32.const 0
i32.const 24
i32.const 280
i32.const 271
i32.const 13
call $~lib/builtins/abort
unreachable
@ -256,7 +256,7 @@
if
i32.const 0
i32.const 24
i32.const 193
i32.const 184
i32.const 13
call $~lib/builtins/abort
unreachable
@ -271,7 +271,7 @@
if
i32.const 0
i32.const 24
i32.const 195
i32.const 186
i32.const 13
call $~lib/builtins/abort
unreachable
@ -370,7 +370,7 @@
if
i32.const 0
i32.const 24
i32.const 216
i32.const 207
i32.const 15
call $~lib/builtins/abort
unreachable
@ -433,7 +433,7 @@
if
i32.const 0
i32.const 24
i32.const 231
i32.const 222
i32.const 13
call $~lib/builtins/abort
unreachable
@ -449,7 +449,7 @@
if
i32.const 0
i32.const 24
i32.const 232
i32.const 223
i32.const 13
call $~lib/builtins/abort
unreachable
@ -506,7 +506,7 @@
if
i32.const 0
i32.const 24
i32.const 248
i32.const 239
i32.const 13
call $~lib/builtins/abort
unreachable
@ -629,7 +629,7 @@
if
i32.const 0
i32.const 24
i32.const 374
i32.const 365
i32.const 4
call $~lib/builtins/abort
unreachable
@ -654,7 +654,7 @@
if
i32.const 0
i32.const 24
i32.const 384
i32.const 375
i32.const 15
call $~lib/builtins/abort
unreachable
@ -685,7 +685,7 @@
if
i32.const 0
i32.const 24
i32.const 396
i32.const 387
i32.const 4
call $~lib/builtins/abort
unreachable
@ -918,7 +918,7 @@
if
i32.const 0
i32.const 24
i32.const 436
i32.const 427
i32.const 29
call $~lib/builtins/abort
unreachable
@ -1012,7 +1012,7 @@
if
i32.const 0
i32.const 24
i32.const 326
i32.const 317
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1077,7 +1077,7 @@
if
i32.const 0
i32.const 24
i32.const 339
i32.const 330
i32.const 17
call $~lib/builtins/abort
unreachable
@ -1195,7 +1195,7 @@
if
i32.const 0
i32.const 24
i32.const 353
i32.const 344
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1306,7 +1306,7 @@
if
i32.const 0
i32.const 24
i32.const 466
i32.const 457
i32.const 15
call $~lib/builtins/abort
unreachable
@ -1324,7 +1324,7 @@
if
i32.const 0
i32.const 24
i32.const 468
i32.const 459
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1347,26 +1347,33 @@
call $~lib/rt/tlsf/prepareBlock
local.get $3
)
(func $~lib/rt/index/__mm_allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
(func $~lib/rt/index/__rt_allocate (; 10 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
global.get $~lib/rt/tlsf/ROOT
local.set $1
local.get $1
local.set $2
local.get $2
i32.eqz
if
call $~lib/rt/tlsf/initializeRoot
global.get $~lib/rt/tlsf/ROOT
local.set $1
local.set $2
end
local.get $1
local.get $2
local.get $0
call $~lib/rt/tlsf/allocateBlock
local.set $3
local.get $3
local.get $1
i32.store offset=8
local.get $3
i32.const 16
i32.add
)
(func $assembly/index/memory.allocate (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
call $~lib/rt/index/__mm_allocate
i32.const 0
call $~lib/rt/index/__rt_allocate
)
(func $~lib/rt/tlsf/freeBlock (; 12 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32)
@ -1381,7 +1388,7 @@
if
i32.const 0
i32.const 24
i32.const 519
i32.const 510
i32.const 2
call $~lib/builtins/abort
unreachable
@ -1395,13 +1402,13 @@
local.get $1
call $~lib/rt/tlsf/insertBlock
)
(func $~lib/rt/index/__mm_free (; 13 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_free (; 13 ;) (type $FUNCSIG$vi) (param $0 i32)
global.get $~lib/rt/tlsf/ROOT
i32.eqz
if
i32.const 0
i32.const 72
i32.const 29
i32.const 31
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1421,7 +1428,7 @@
if
i32.const 0
i32.const 72
i32.const 30
i32.const 32
i32.const 2
call $~lib/builtins/abort
unreachable
@ -1434,7 +1441,7 @@
)
(func $assembly/index/memory.free (; 14 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
call $~lib/rt/index/__mm_free
call $~lib/rt/index/__rt_free
)
(func $~lib/memory/memory.fill (; 15 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)

View File

@ -1,12 +1,13 @@
import "rt";
export {
__mm_allocate,
__mm_reallocate,
__mm_free,
__gc_retain,
__gc_release,
__gc_collect
__rt_allocate,
__rt_reallocate,
__rt_free,
__rt_retain,
__rt_release,
__rt_collect,
__rt_typeinfo
};
@start export function main(): void {}

View File

@ -28,8 +28,8 @@ fetch("untouched.wasm").then(result =>
).then(result => {
exports = result.instance.exports;
U32 = new Uint32Array(exports.memory.buffer);
var first = exports.__mm_allocate(255);
exports.__mm_free(first);
var first = exports.__rt_allocate(255);
exports.__rt_free(first);
ROOT = first - 17;
while (!U32[ROOT >> 2]) --ROOT; // find tail
ROOT -= (1 + FL_BITS + HL_SIZE) << 2;
@ -113,7 +113,7 @@ function update() {
}
function allocate(size) {
var ptr = exports.__mm_allocate(size);
var ptr = exports.__rt_allocate(size);
if (!ptr) {
alert("should not happen");
return;
@ -127,7 +127,7 @@ function allocate(size) {
var er = document.createElement("button");
er.innerText = "realloc";
er.onclick = function() {
ptr = exports.__mm_reallocate(ptr, es.value >>> 0);
ptr = exports.__rt_reallocate(ptr, es.value >>> 0);
update();
};
el.appendChild(er);
@ -136,7 +136,7 @@ function allocate(size) {
ef.className = "free";
el.appendChild(ef);
ef.onclick = function() {
exports.__mm_free(ptr);
exports.__rt_free(ptr);
document.getElementById("segs").removeChild(el);
update();
};

View File

@ -1,9 +1,9 @@
(module
(type $FUNCSIG$v (func))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
(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$viii (func (param i32 i32 i32)))
(type $FUNCSIG$vi (func (param i32)))
@ -13,18 +13,20 @@
(data (i32.const 24) "~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s")
(data (i32.const 56) "\10\00\00\00\1c")
(data (i32.const 72) "~\00l\00i\00b\00/\00m\00e\00m\00o\00r\00y\00.\00t\00s")
(data (i32.const 104) "\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 $~lib/started (mut i32) (i32.const 0))
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
(global $~lib/rt/pure/CUR (mut i32) (i32.const 0))
(global $~lib/rt/pure/ROOTS (mut i32) (i32.const 0))
(export "memory" (memory $0))
(export "main" (func $assembly/index/main))
(export "__mm_allocate" (func $~lib/rt/index/__mm_allocate))
(export "__mm_reallocate" (func $~lib/rt/index/__mm_reallocate))
(export "__mm_free" (func $~lib/rt/index/__mm_free))
(export "__gc_retain" (func $~lib/rt/index/__gc_retain))
(export "__gc_release" (func $~lib/rt/index/__gc_release))
(export "__gc_collect" (func $~lib/rt/index/__gc_collect))
(export "__rt_allocate" (func $~lib/rt/index/__rt_allocate))
(export "__rt_reallocate" (func $~lib/rt/index/__rt_reallocate))
(export "__rt_free" (func $~lib/rt/index/__rt_free))
(export "__rt_retain" (func $~lib/rt/index/__rt_retain))
(export "__rt_release" (func $~lib/rt/index/__rt_release))
(export "__rt_collect" (func $~lib/rt/index/__rt_collect))
(export "__rt_typeinfo" (func $~lib/rt/common/__rt_typeinfo))
(func $assembly/index/main (; 1 ;) (type $FUNCSIG$v)
global.get $~lib/started
i32.eqz
@ -416,7 +418,7 @@
(local $1 i32)
(local $2 i32)
(local $3 i32)
i32.const 112
i32.const 240
local.tee $3
i32.const 67107
i32.add
@ -515,7 +517,7 @@
if
i32.const 0
i32.const 24
i32.const 436
i32.const 427
i32.const 29
call $~lib/builtins/abort
unreachable
@ -776,18 +778,22 @@
call $~lib/rt/tlsf/prepareBlock
local.get $2
)
(func $~lib/rt/index/__mm_allocate (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
(func $~lib/rt/index/__rt_allocate (; 11 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
global.get $~lib/rt/tlsf/ROOT
local.tee $1
local.tee $2
if (result i32)
local.get $1
local.get $2
else
call $~lib/rt/tlsf/initializeRoot
global.get $~lib/rt/tlsf/ROOT
end
local.get $0
call $~lib/rt/tlsf/allocateBlock
local.tee $0
local.get $1
i32.store offset=8
local.get $0
i32.const 16
i32.add
)
@ -1067,7 +1073,7 @@
call $~lib/rt/tlsf/insertBlock
local.get $3
)
(func $~lib/rt/index/__mm_reallocate (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/rt/index/__rt_reallocate (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
global.get $~lib/rt/tlsf/ROOT
local.get $0
i32.const 16
@ -1088,14 +1094,14 @@
local.get $1
call $~lib/rt/tlsf/insertBlock
)
(func $~lib/rt/index/__mm_free (; 16 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_free (; 16 ;) (type $FUNCSIG$vi) (param $0 i32)
global.get $~lib/rt/tlsf/ROOT
local.get $0
i32.const 16
i32.sub
call $~lib/rt/tlsf/freeBlock
)
(func $~lib/rt/index/__gc_retain (; 17 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_retain (; 17 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
if
local.get $0
@ -1109,7 +1115,7 @@
i32.store offset=4
end
)
(func $~lib/rt/index/__gc_release (; 18 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_release (; 18 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
if
local.get $0
@ -1327,10 +1333,34 @@
local.get $5
global.set $~lib/rt/pure/CUR
)
(func $~lib/rt/index/__gc_collect (; 23 ;) (type $FUNCSIG$v)
(func $~lib/rt/index/__rt_collect (; 23 ;) (type $FUNCSIG$v)
call $~lib/rt/pure/collectCycles
)
(func $start (; 24 ;) (type $FUNCSIG$v)
(func $~lib/rt/common/__rt_typeinfo (; 24 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
i32.const 104
local.set $1
local.get $0
if (result i32)
local.get $0
local.get $1
i32.load
i32.gt_u
else
i32.const 1
end
if (result i32)
unreachable
else
local.get $1
local.get $0
i32.const 3
i32.shl
i32.add
i32.load
end
)
(func $start (; 25 ;) (type $FUNCSIG$v)
nop
)
)

Binary file not shown.

View File

@ -1,10 +1,10 @@
(module
(type $FUNCSIG$v (func))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$viii (func (param i32 i32 i32)))
(type $FUNCSIG$vi (func (param i32)))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
@ -13,6 +13,7 @@
(data (i32.const 56) "\10\00\00\00 \00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00n\00d\00e\00x\00.\00t\00s\00")
(data (i32.const 104) "\10\00\00\00\1e\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00p\00u\00r\00e\00.\00t\00s\00")
(data (i32.const 152) "\10\00\00\00\1c\00\00\00\00\00\00\00\00\00\00\00~\00l\00i\00b\00/\00m\00e\00m\00o\00r\00y\00.\00t\00s\00")
(data (i32.const 200) "\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 $~lib/rt/pure/ACYCLIC_FLAG i32 (i32.const 0))
@ -21,15 +22,17 @@
(global $~lib/rt/pure/CUR (mut i32) (i32.const 0))
(global $~lib/rt/pure/END (mut i32) (i32.const 0))
(global $~lib/rt/pure/ROOTS (mut i32) (i32.const 0))
(global $~lib/memory/HEAP_BASE i32 (i32.const 196))
(global $~lib/runtime/RTTI_BASE i32 (i32.const 200))
(global $~lib/memory/HEAP_BASE i32 (i32.const 336))
(export "memory" (memory $0))
(export "main" (func $assembly/index/main))
(export "__mm_allocate" (func $~lib/rt/index/__mm_allocate))
(export "__mm_reallocate" (func $~lib/rt/index/__mm_reallocate))
(export "__mm_free" (func $~lib/rt/index/__mm_free))
(export "__gc_retain" (func $~lib/rt/index/__gc_retain))
(export "__gc_release" (func $~lib/rt/index/__gc_release))
(export "__gc_collect" (func $~lib/rt/index/__gc_collect))
(export "__rt_allocate" (func $~lib/rt/index/__rt_allocate))
(export "__rt_reallocate" (func $~lib/rt/index/__rt_reallocate))
(export "__rt_free" (func $~lib/rt/index/__rt_free))
(export "__rt_retain" (func $~lib/rt/index/__rt_retain))
(export "__rt_release" (func $~lib/rt/index/__rt_release))
(export "__rt_collect" (func $~lib/rt/index/__rt_collect))
(export "__rt_typeinfo" (func $~lib/rt/common/__rt_typeinfo))
(func $assembly/index/main (; 1 ;) (type $FUNCSIG$v)
global.get $~lib/started
i32.eqz
@ -60,7 +63,7 @@
if
i32.const 0
i32.const 24
i32.const 265
i32.const 256
i32.const 13
call $~lib/builtins/abort
unreachable
@ -85,7 +88,7 @@
if
i32.const 0
i32.const 24
i32.const 267
i32.const 258
i32.const 13
call $~lib/builtins/abort
unreachable
@ -137,7 +140,7 @@
if
i32.const 0
i32.const 24
i32.const 280
i32.const 271
i32.const 13
call $~lib/builtins/abort
unreachable
@ -275,7 +278,7 @@
if
i32.const 0
i32.const 24
i32.const 193
i32.const 184
i32.const 13
call $~lib/builtins/abort
unreachable
@ -290,7 +293,7 @@
if
i32.const 0
i32.const 24
i32.const 195
i32.const 186
i32.const 13
call $~lib/builtins/abort
unreachable
@ -389,7 +392,7 @@
if
i32.const 0
i32.const 24
i32.const 216
i32.const 207
i32.const 15
call $~lib/builtins/abort
unreachable
@ -452,7 +455,7 @@
if
i32.const 0
i32.const 24
i32.const 231
i32.const 222
i32.const 13
call $~lib/builtins/abort
unreachable
@ -468,7 +471,7 @@
if
i32.const 0
i32.const 24
i32.const 232
i32.const 223
i32.const 13
call $~lib/builtins/abort
unreachable
@ -525,7 +528,7 @@
if
i32.const 0
i32.const 24
i32.const 248
i32.const 239
i32.const 13
call $~lib/builtins/abort
unreachable
@ -648,7 +651,7 @@
if
i32.const 0
i32.const 24
i32.const 374
i32.const 365
i32.const 4
call $~lib/builtins/abort
unreachable
@ -673,7 +676,7 @@
if
i32.const 0
i32.const 24
i32.const 384
i32.const 375
i32.const 15
call $~lib/builtins/abort
unreachable
@ -704,7 +707,7 @@
if
i32.const 0
i32.const 24
i32.const 396
i32.const 387
i32.const 4
call $~lib/builtins/abort
unreachable
@ -937,7 +940,7 @@
if
i32.const 0
i32.const 24
i32.const 436
i32.const 427
i32.const 29
call $~lib/builtins/abort
unreachable
@ -1031,7 +1034,7 @@
if
i32.const 0
i32.const 24
i32.const 326
i32.const 317
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1096,7 +1099,7 @@
if
i32.const 0
i32.const 24
i32.const 339
i32.const 330
i32.const 17
call $~lib/builtins/abort
unreachable
@ -1214,7 +1217,7 @@
if
i32.const 0
i32.const 24
i32.const 353
i32.const 344
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1325,7 +1328,7 @@
if
i32.const 0
i32.const 24
i32.const 466
i32.const 457
i32.const 15
call $~lib/builtins/abort
unreachable
@ -1343,7 +1346,7 @@
if
i32.const 0
i32.const 24
i32.const 468
i32.const 459
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1366,20 +1369,26 @@
call $~lib/rt/tlsf/prepareBlock
local.get $3
)
(func $~lib/rt/index/__mm_allocate (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
(func $~lib/rt/index/__rt_allocate (; 11 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
global.get $~lib/rt/tlsf/ROOT
local.set $1
local.get $1
local.set $2
local.get $2
i32.eqz
if
call $~lib/rt/tlsf/initializeRoot
global.get $~lib/rt/tlsf/ROOT
local.set $1
local.set $2
end
local.get $1
local.get $2
local.get $0
call $~lib/rt/tlsf/allocateBlock
local.set $3
local.get $3
local.get $1
i32.store offset=8
local.get $3
i32.const 16
i32.add
)
@ -1613,7 +1622,7 @@
if
i32.const 0
i32.const 24
i32.const 481
i32.const 472
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1727,13 +1736,13 @@
call $~lib/rt/tlsf/insertBlock
local.get $8
)
(func $~lib/rt/index/__mm_reallocate (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/rt/index/__rt_reallocate (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
global.get $~lib/rt/tlsf/ROOT
i32.eqz
if
i32.const 0
i32.const 72
i32.const 21
i32.const 23
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1753,7 +1762,7 @@
if
i32.const 0
i32.const 72
i32.const 22
i32.const 24
i32.const 2
call $~lib/builtins/abort
unreachable
@ -1780,7 +1789,7 @@
if
i32.const 0
i32.const 24
i32.const 519
i32.const 510
i32.const 2
call $~lib/builtins/abort
unreachable
@ -1794,13 +1803,13 @@
local.get $1
call $~lib/rt/tlsf/insertBlock
)
(func $~lib/rt/index/__mm_free (; 16 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_free (; 16 ;) (type $FUNCSIG$vi) (param $0 i32)
global.get $~lib/rt/tlsf/ROOT
i32.eqz
if
i32.const 0
i32.const 72
i32.const 29
i32.const 31
i32.const 13
call $~lib/builtins/abort
unreachable
@ -1820,7 +1829,7 @@
if
i32.const 0
i32.const 72
i32.const 30
i32.const 32
i32.const 2
call $~lib/builtins/abort
unreachable
@ -1864,7 +1873,7 @@
i32.add
i32.store offset=4
)
(func $~lib/rt/index/__gc_retain (; 18 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_retain (; 18 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
if
local.get $0
@ -2037,7 +2046,7 @@
end
end
)
(func $~lib/rt/index/__gc_release (; 25 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/rt/index/__rt_release (; 25 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
if
local.get $0
@ -2300,11 +2309,36 @@
local.get $0
global.set $~lib/rt/pure/CUR
)
(func $~lib/rt/index/__gc_collect (; 31 ;) (type $FUNCSIG$v)
(func $~lib/rt/index/__rt_collect (; 31 ;) (type $FUNCSIG$v)
call $~lib/rt/pure/collectCycles
)
(func $start (; 32 ;) (type $FUNCSIG$v)
(func $~lib/rt/common/__rt_typeinfo (; 32 ;) (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 $null (; 33 ;) (type $FUNCSIG$v)
(func $start (; 33 ;) (type $FUNCSIG$v)
)
(func $null (; 34 ;) (type $FUNCSIG$v)
)
)