diff --git a/std/assembly/rt/README.md b/std/assembly/rt/README.md
index c930576e..1fb78f57 100644
--- a/std/assembly/rt/README.md
+++ b/std/assembly/rt/README.md
@@ -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`
+ 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`
+ Frees a dynamically allocated chunk of memory by its address.
+
+* **__rt_retain**(ref: `usize`): `void`
+ Retains a reference.
+
+* **__rt_release**(ref: `usize`): `void`
+ Releases a reference.
+
+* **__rt_collect**(): `void`
+ Forces a full garbage collection cycle.
+
+* **__rt_typeinfo**(id: `u32`): `void`
+ 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.
diff --git a/std/assembly/rt/common.ts b/std/assembly/rt/common.ts
index e8062635..97af07d6 100644
--- a/std/assembly/rt/common.ts
+++ b/std/assembly/rt/common.ts
@@ -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(ptr)
+ ? unreachable()
+ : changetype(ptr + id * offsetof()).flags;
+}
diff --git a/std/assembly/rt/index.ts b/std/assembly/rt/index.ts
index cdd95244..a37cf887 100644
--- a/std/assembly/rt/index.ts
+++ b/std/assembly/rt/index.ts
@@ -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(allocateBlock(root, size)) + BLOCK_OVERHEAD;
+ var block = allocateBlock(root, size);
+ block.rtId = id;
+ return changetype(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(reallocateBlock(ROOT, changetype(data - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD;
+ assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
+ return changetype(reallocateBlock(ROOT, changetype(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(data - BLOCK_OVERHEAD));
+ assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
+ freeBlock(ROOT, changetype(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(ref - BLOCK_OVERHEAD));
}
// @ts-ignore: decorator
@global @unsafe
-function __gc_release(ref: usize): void {
+function __rt_release(ref: usize): void {
if (ref) decrement(changetype(ref - BLOCK_OVERHEAD));
}
// @ts-ignore: decorator
@global @unsafe
-function __gc_collect(): void {
+function __rt_collect(): void {
collectCycles();
}
diff --git a/std/assembly/rt/stub.ts b/std/assembly/rt/stub.ts
new file mode 100644
index 00000000..da02be77
--- /dev/null
+++ b/std/assembly/rt/stub.ts
@@ -0,0 +1,77 @@
+import { AL_MASK, CommonBlock } from "./common";
+
+// @ts-ignore: decorator
+@inline
+const BLOCK_OVERHEAD = offsetof();
+
+// @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(size, 1) + AL_MASK) & ~AL_MASK;
+ var pagesBefore = memory.size();
+ if (newPtr > 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(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(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 {
+}
diff --git a/std/assembly/rt/tlsf.ts b/std/assembly/rt/tlsf.ts
index 8b9bfbea..518908a2 100644
--- a/std/assembly/rt/tlsf.ts
+++ b/std/assembly/rt/tlsf.ts
@@ -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;
diff --git a/tests/allocators/asrt/assembly/index.ts b/tests/allocators/rt/assembly/index.ts
similarity index 84%
rename from tests/allocators/asrt/assembly/index.ts
rename to tests/allocators/rt/assembly/index.ts
index f2af0bf0..07ddc5a5 100644
--- a/tests/allocators/asrt/assembly/index.ts
+++ b/tests/allocators/rt/assembly/index.ts
@@ -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);
diff --git a/tests/allocators/asrt/assembly/tsconfig.json b/tests/allocators/rt/assembly/tsconfig.json
similarity index 100%
rename from tests/allocators/asrt/assembly/tsconfig.json
rename to tests/allocators/rt/assembly/tsconfig.json
diff --git a/tests/allocators/asrt/optimized.wat b/tests/allocators/rt/optimized.wat
similarity index 96%
rename from tests/allocators/asrt/optimized.wat
rename to tests/allocators/rt/optimized.wat
index 40afeeef..7b5eb5ce 100644
--- a/tests/allocators/asrt/optimized.wat
+++ b/tests/allocators/rt/optimized.wat
@@ -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
)
)
diff --git a/tests/allocators/asrt/package.json b/tests/allocators/rt/package.json
similarity index 100%
rename from tests/allocators/asrt/package.json
rename to tests/allocators/rt/package.json
diff --git a/tests/allocators/asrt/untouched.wat b/tests/allocators/rt/untouched.wat
similarity index 97%
rename from tests/allocators/asrt/untouched.wat
rename to tests/allocators/rt/untouched.wat
index 5e0390d1..1667756b 100644
--- a/tests/allocators/asrt/untouched.wat
+++ b/tests/allocators/rt/untouched.wat
@@ -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)
diff --git a/tests/runtime/assembly/index.ts b/tests/runtime/assembly/index.ts
index e10336b7..18f2db53 100644
--- a/tests/runtime/assembly/index.ts
+++ b/tests/runtime/assembly/index.ts
@@ -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 {}
diff --git a/tests/runtime/index.html b/tests/runtime/index.html
index d029c223..f7f8b46c 100644
--- a/tests/runtime/index.html
+++ b/tests/runtime/index.html
@@ -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();
};
diff --git a/tests/runtime/optimized.wat b/tests/runtime/optimized.wat
index f35cbe3e..fb233542 100644
--- a/tests/runtime/optimized.wat
+++ b/tests/runtime/optimized.wat
@@ -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
)
)
diff --git a/tests/runtime/untouched.wasm b/tests/runtime/untouched.wasm
index b84c7aa0..e6bc7cdd 100644
Binary files a/tests/runtime/untouched.wasm and b/tests/runtime/untouched.wasm differ
diff --git a/tests/runtime/untouched.wat b/tests/runtime/untouched.wat
index e3f74648..267a1056 100644
--- a/tests/runtime/untouched.wat
+++ b/tests/runtime/untouched.wat
@@ -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)
)
)