This commit is contained in:
dcode 2019-03-14 12:46:36 +01:00
parent cdf3e2cf12
commit 3a60638f72
12 changed files with 627 additions and 662 deletions

View File

@ -1,4 +1,5 @@
import { runtime, ArrayBufferView } from "./runtime";
import { gc } from "./gc";
import { ArrayBuffer } from "./arraybuffer";
import { COMPARATOR, SORT } from "./util/sort";
import { itoa, dtoa, itoa_stream, dtoa_stream, MAX_DOUBLE_LENGTH } from "./util/number";
@ -76,7 +77,7 @@ export class Array<T> extends ArrayBufferView {
private __set(index: i32, value: T): void {
this.resize(index + 1);
store<T>(this.dataStart + (<usize>index << alignof<T>()), value);
if (isManaged<T>()) runtime.link(changetype<usize>(value), changetype<usize>(this));
if (isManaged<T>()) gc.link(value, this);
if (index >= this.length_) this.length_ = index + 1;
}
@ -141,7 +142,7 @@ export class Array<T> extends ArrayBufferView {
this.resize(newLength);
this.length_ = newLength;
store<T>(this.dataStart + (<usize>(newLength - 1) << alignof<T>()), element);
if (isManaged<T>()) runtime.link(changetype<usize>(element), changetype<usize>(this));
if (isManaged<T>()) gc.link(element, this);
return newLength;
}
@ -156,14 +157,14 @@ export class Array<T> extends ArrayBufferView {
for (let offset: usize = 0; offset < thisSize; offset += sizeof<T>()) {
let element = load<T>(thisStart + offset);
store<T>(outStart + offset, element);
runtime.link(changetype<usize>(element), changetype<usize>(out));
gc.link(element, out);
}
let otherStart = other.dataStart;
let otherSize = <usize>otherLen << alignof<T>();
for (let offset: usize = 0; offset < otherSize; offset += sizeof<T>()) {
let element = load<T>(otherStart + offset);
store<T>(outStart + thisSize + offset, element);
runtime.link(changetype<usize>(element), changetype<usize>(out));
gc.link(element, out);
}
} else {
memory.copy(outStart, this.dataStart, thisSize);
@ -221,7 +222,7 @@ export class Array<T> extends ArrayBufferView {
let value = load<T>(this.dataStart + (<usize>index << alignof<T>()));
let result = callbackfn(value, index, this);
store<U>(outStart + (<usize>index << alignof<U>()), result);
if (isManaged<U>()) runtime.link(changetype<usize>(result), changetype<usize>(out));
if (isManaged<U>()) gc.link(result, out);
}
return out;
}
@ -293,7 +294,7 @@ export class Array<T> extends ArrayBufferView {
<usize>(newLength - 1) << alignof<T>()
);
store<T>(base, element);
if (isManaged<T>()) runtime.link(changetype<usize>(element), changetype<usize>(this));
if (isManaged<T>()) gc.link(element, this);
this.length_ = newLength;
return newLength;
}
@ -310,7 +311,7 @@ export class Array<T> extends ArrayBufferView {
let offset = <usize>i << alignof<T>();
let element = load<T>(thisBase + offset);
store<T>(sliceBase + offset, element);
if (isManaged<T>()) runtime.link(changetype<usize>(element), changetype<usize>(slice));
if (isManaged<T>()) gc.link(element, slice);
}
return slice;
}
@ -326,7 +327,7 @@ export class Array<T> extends ArrayBufferView {
for (let i = 0; i < deleteCount; ++i) {
let element = load<T>(thisBase + (<usize>i << alignof<T>()));
store<T>(spliceStart + (<usize>i << alignof<T>()), element);
if (isManaged<T>()) runtime.link(changetype<usize>(element), changetype<usize>(splice));
if (isManaged<T>()) gc.link(element, splice);
}
memory.copy(
splice.dataStart,
@ -428,16 +429,17 @@ export class Array<T> extends ArrayBufferView {
if (estLen > offset) {
let trimmed = changetype<string>(result).substring(0, offset);
runtime.free(result);
runtime.freeUnregistered(result);
return trimmed; // registered in .substring
}
return runtime.register<string>(result);
return gc.register<string>(result);
}
private join_int(separator: string = ","): string {
var lastIndex = this.length_ - 1;
if (lastIndex < 0) return "";
var dataStart = this.dataStart;
// @ts-ignore: type
if (!lastIndex) return changetype<string>(itoa<T>(load<T>(dataStart)));
var sepLen = separator.length;
@ -448,6 +450,7 @@ export class Array<T> extends ArrayBufferView {
var value: T;
for (let i = 0; i < lastIndex; ++i) {
value = load<T>(dataStart + (<usize>i << alignof<T>()));
// @ts-ignore: type
offset += itoa_stream<T>(result, offset, value);
if (sepLen) {
memory.copy(
@ -459,13 +462,14 @@ export class Array<T> extends ArrayBufferView {
}
}
value = load<T>(dataStart + (<usize>lastIndex << alignof<T>()));
// @ts-ignore: type
offset += itoa_stream<T>(result, offset, value);
if (estLen > offset) {
let trimmed = changetype<string>(result).substring(0, offset);
runtime.free(result);
runtime.freeUnregistered(result);
return trimmed; // registered in .substring
}
return runtime.register<string>(result);
return gc.register<string>(result);
}
private join_flt(separator: string = ","): string {
@ -507,10 +511,10 @@ export class Array<T> extends ArrayBufferView {
);
if (estLen > offset) {
let trimmed = changetype<string>(result).substring(0, offset);
runtime.free(result);
runtime.freeUnregistered(result);
return trimmed; // registered in .substring
}
return runtime.register<string>(result);
return gc.register<string>(result);
}
private join_str(separator: string = ","): string {
@ -556,7 +560,7 @@ export class Array<T> extends ArrayBufferView {
<usize>valueLen << 1
);
}
return runtime.register<string>(result);
return gc.register<string>(result);
}
private join_arr(separator: string = ","): string {
@ -625,10 +629,10 @@ export class Array<T> extends ArrayBufferView {
}
if (estLen > offset) {
let out = changetype<string>(result).substring(0, offset);
runtime.free(result);
runtime.freeUnregistered(result);
return out; // registered in .substring
}
return runtime.register<string>(result);
return gc.register<string>(result);
}
@inline

View File

@ -1,4 +1,5 @@
import { runtime, ArrayBufferView } from "./runtime";
import { gc } from "./gc";
@sealed export class ArrayBuffer {
@ -22,7 +23,9 @@ import { runtime, ArrayBufferView } from "./runtime";
constructor(length: i32) {
if (<u32>length > <u32>ArrayBufferView.MAX_BYTELENGTH) throw new RangeError("Invalid array buffer length");
return runtime.register<ArrayBuffer>(runtime.alloc(<usize>length));
var buffer = runtime.alloc(<usize>length);
memory.fill(changetype<usize>(buffer), 0, <usize>length);
return gc.register<ArrayBuffer>(buffer);
}
get byteLength(): i32 {
@ -34,9 +37,9 @@ import { runtime, ArrayBufferView } from "./runtime";
begin = begin < 0 ? max(length + begin, 0) : min(begin, length);
end = end < 0 ? max(length + end , 0) : min(end , length);
var outSize = <usize>max(end - begin, 0);
var out = runtime.allocRaw(outSize);
var out = runtime.alloc(outSize);
memory.copy(out, changetype<usize>(this) + <usize>begin, outSize);
return runtime.register<ArrayBuffer>(out);
return gc.register<ArrayBuffer>(out);
}
toString(): string {

View File

@ -1,3 +1,5 @@
import { runtime } from "./runtime";
/** Garbage collector interface. */
export namespace gc {
@ -21,20 +23,23 @@ export namespace gc {
/** Registers a managed object to be tracked by the garbage collector. */
// @ts-ignore: decorator
@unsafe
export function register(ref: usize): void {
@unsafe @inline
export function register<T>(ref: usize): T {
runtime.unrefUnregistered(ref).classId = classId<T>();
// @ts-ignore: stub
if (isDefined(__gc_register)) __gc_register(ref);
else ERROR("missing implementation: gc.register");
return changetype<T>(ref);
}
/** Links a registered object with the registered object now referencing it. */
// @ts-ignore: decorator
@unsafe
export function link(ref: usize, parentRef: usize): void {
@unsafe @inline
export function link<T, TParent>(ref: T, parentRef: TParent): void {
assert(changetype<usize>(ref) >= HEAP_BASE + runtime.Header.SIZE); // must be a heap object
var header = changetype<runtime.Header>(changetype<usize>(ref) - runtime.Header.SIZE);
assert(header.classId != runtime.Header.MAGIC && header.gc1 != 0 && header.gc2 != 0); // must be registered
// @ts-ignore: stub
if (isDefined(__gc_link)) __gc_link(ref, parentRef);
else ERROR("missing implementation: gc.link");
}
/** Marks an object as being reachable. */

View File

@ -1,4 +1,4 @@
import { runtime } from "./runtime";
import { gc } from "./gc";
import { HASH } from "./util/hash";
// A deterministic hash map based on CloseTable from https://github.com/jorendorff/dht
@ -124,8 +124,8 @@ export class Map<K,V> {
let bucketPtrBase = changetype<usize>(this.buckets) + <usize>(hashCode & this.bucketsMask) * BUCKET_SIZE;
entry.taggedNext = load<usize>(bucketPtrBase);
store<usize>(bucketPtrBase, changetype<usize>(entry));
if (isManaged<K>()) runtime.link(changetype<usize>(key), changetype<usize>(this));
if (isManaged<V>()) runtime.link(changetype<usize>(value), changetype<usize>(this));
if (isManaged<K>()) gc.link(key, this);
if (isManaged<V>()) gc.link(value, this);
}
}

View File

@ -48,7 +48,7 @@ export namespace runtime {
/** Allocates a new object and returns a pointer to its payload. Does not fill. */
// @ts-ignore: decorator
@unsafe
export function allocRaw(payloadSize: u32): usize {
export function alloc(payloadSize: u32): usize {
var header = changetype<Header>(memory.allocate(adjust(payloadSize)));
header.classId = Header.MAGIC;
header.payloadSize = payloadSize;
@ -59,15 +59,6 @@ export namespace runtime {
return changetype<usize>(header) + Header.SIZE;
}
/** Allocates a new object and returns a pointer to its payload. Fills with zeroes.*/
// @ts-ignore: decorator
@unsafe
export function alloc(payloadSize: u32): usize {
var ref = allocRaw(payloadSize);
memory.fill(ref, 0, payloadSize);
return ref;
}
/** Reallocates an object if necessary. Returns a pointer to its (moved) payload. */
// @ts-ignore: decorator
@unsafe
@ -83,7 +74,7 @@ export namespace runtime {
if (select(adjust(payloadSize), 0, ref > HEAP_BASE) < newAdjustedSize) {
// move if the allocation isn't large enough or not a heap object
let newHeader = changetype<Header>(memory.allocate(newAdjustedSize));
newHeader.classId = Header.MAGIC;
newHeader.classId = header.classId;
if (gc.implemented) {
newHeader.gc1 = 0;
newHeader.gc2 = 0;
@ -97,7 +88,8 @@ export namespace runtime {
memory.free(changetype<usize>(header));
} else if (gc.implemented) {
// if previously registered, register again
gc.register(ref);
// @ts-ignore: stub
__gc_register(ref);
}
header = newHeader;
ref = newRef;
@ -113,40 +105,20 @@ export namespace runtime {
return ref;
}
function unref(ref: usize): Header {
// @ts-ignore: decorator
@unsafe
export function unrefUnregistered(ref: usize): Header {
assert(ref >= HEAP_BASE + Header.SIZE); // must be a heap object
var header = changetype<Header>(ref - Header.SIZE);
assert(header.classId == Header.MAGIC); // must be unregistered
return header;
}
/** Frees an object. Must not have been registered with GC yet. */
/** Frees an unregistered object that turned out to be unnecessary. */
// @ts-ignore: decorator
@unsafe @inline
export function free<T>(ref: T): void {
memory.free(changetype<usize>(unref(changetype<usize>(ref))));
}
/** Registers a managed object. Cannot be free'd anymore afterwards. */
// @ts-ignore: decorator
@unsafe @inline
export function register<T>(ref: usize): T {
if (!isReference<T>()) ERROR("reference expected");
// see comment in REALLOC why this is useful. also inline this because
// it's generic so we don't get a bunch of functions.
unref(ref).classId = gc.classId<T>();
if (gc.implemented) gc.register(ref);
return changetype<T>(ref);
}
/** Links a managed object with its managed parent. */
// @ts-ignore: decorator
@unsafe @inline
export function link<T, TParent>(ref: T, parentRef: TParent): void {
assert(changetype<usize>(ref) >= HEAP_BASE + Header.SIZE); // must be a heap object
var header = changetype<Header>(changetype<usize>(ref) - Header.SIZE);
assert(header.classId != Header.MAGIC && header.gc1 != 0 && header.gc2 != 0); // must be registered
if (gc.implemented) gc.link(changetype<usize>(ref), changetype<usize>(parentRef)); // tslint:disable-line
export function freeUnregistered<T>(ref: T): void {
memory.free(changetype<usize>(unrefUnregistered(changetype<usize>(ref))));
}
}

View File

@ -1,4 +1,4 @@
import { runtime } from "./runtime";
import { gc } from "./gc";
import { HASH } from "./util/hash";
// A deterministic hash set based on CloseTable from https://github.com/jorendorff/dht
@ -70,7 +70,7 @@ export class Set<K> {
this.buckets = new ArrayBuffer(bucketsSize);
this.bucketsMask = INITIAL_CAPACITY - 1;
const entriesSize = INITIAL_CAPACITY * <i32>ENTRY_SIZE<K>();
this.entries = new ArrayBuffer(entriesSize, true);
this.entries = new ArrayBuffer(entriesSize);
this.entriesCapacity = INITIAL_CAPACITY;
this.entriesOffset = 0;
this.entriesCount = 0;
@ -114,7 +114,7 @@ export class Set<K> {
let bucketPtrBase = changetype<usize>(this.buckets) + <usize>(hashCode & this.bucketsMask) * BUCKET_SIZE;
entry.taggedNext = load<usize>(bucketPtrBase);
store<usize>(bucketPtrBase, changetype<usize>(entry));
if (isManaged<K>()) runtime.link(changetype<usize>(key), changetype<usize>(this)); // tslint:disable-line
if (isManaged<K>()) gc.link(key, this);
}
}
@ -136,7 +136,7 @@ export class Set<K> {
var newBucketsCapacity = <i32>(newBucketsMask + 1);
var newBuckets = new ArrayBuffer(newBucketsCapacity * <i32>BUCKET_SIZE);
var newEntriesCapacity = <i32>(newBucketsCapacity * FILL_FACTOR);
var newEntries = new ArrayBuffer(newEntriesCapacity * <i32>ENTRY_SIZE<K>(), true);
var newEntries = new ArrayBuffer(newEntriesCapacity * <i32>ENTRY_SIZE<K>());
// copy old entries to new entries
var oldPtr = changetype<usize>(this.entries);

View File

@ -1,4 +1,5 @@
import { runtime } from "./runtime";
import { gc } from "./gc";
import { MAX_SIZE_32 } from "./util/allocator";
import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./util/string";
@ -14,15 +15,15 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
// TODO Add and handle second argument
static fromCharCode(code: i32): String {
var out = runtime.allocRaw(2);
var out = runtime.alloc(2);
store<u16>(out, <u16>code);
return runtime.register<String>(out);
return gc.register<String>(out);
}
static fromCodePoint(code: i32): String {
assert(<u32>code <= 0x10FFFF);
var sur = code > 0xFFFF;
var out = runtime.allocRaw((i32(sur) + 1) << 1);
var out = runtime.alloc((i32(sur) + 1) << 1);
if (!sur) {
store<u16>(out, <u16>code);
} else {
@ -31,15 +32,15 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
let lo: u32 = (code & 0x3FF) + 0xDC00;
store<u32>(out, (hi << 16) | lo);
}
return runtime.register<String>(out);
return gc.register<String>(out);
}
@operator("[]") charAt(pos: i32): String {
assert(this !== null);
if (<u32>pos >= <u32>this.length) return changetype<String>("");
var out = runtime.allocRaw(2);
var out = runtime.alloc(2);
store<u16>(out, load<u16>(changetype<usize>(this) + (<usize>pos << 1)));
return runtime.register<String>(out);
return gc.register<String>(out);
}
charCodeAt(pos: i32): i32 {
@ -70,10 +71,10 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
var otherSize: isize = other.length << 1;
var outSize: usize = thisSize + otherSize;
if (outSize == 0) return changetype<String>("");
var out = runtime.allocRaw(outSize);
var out = runtime.alloc(outSize);
memory.copy(out, changetype<usize>(this), thisSize);
memory.copy(out + thisSize, changetype<usize>(other), otherSize);
return runtime.register<String>(out);
return gc.register<String>(out);
}
endsWith(searchString: String, endPosition: i32 = String.MAX_LENGTH): bool {
@ -183,9 +184,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
if (intStart < 0) intStart = max(size + intStart, 0);
var resultLength = min(max(end, 0), size - intStart);
if (resultLength <= 0) return changetype<String>("");
var out = runtime.allocRaw(resultLength << 1);
var out = runtime.alloc(resultLength << 1);
memory.copy(out, changetype<usize>(this) + intStart, resultLength);
return runtime.register<String>(out);
return gc.register<String>(out);
}
substring(start: i32, end: i32 = i32.MAX_VALUE): String {
@ -198,9 +199,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
len = toPos - fromPos;
if (!len) return changetype<String>("");
if (!fromPos && toPos == this.length << 1) return this;
var out = runtime.allocRaw(len);
var out = runtime.alloc(len);
memory.copy(out, changetype<usize>(this) + fromPos, len);
return runtime.register<String>(out);
return gc.register<String>(out);
}
trim(): String {
@ -226,9 +227,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
}
if (!size) return changetype<String>("");
if (!start && size == length << 1) return this;
var out = runtime.allocRaw(size);
var out = runtime.alloc(size);
memory.copy(out, changetype<usize>(this) + offset, size);
return runtime.register<String>(out);
return gc.register<String>(out);
}
@inline
@ -256,9 +257,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
if (!offset) return this;
size -= offset;
if (!size) return changetype<String>("");
var out = runtime.allocRaw(size);
var out = runtime.alloc(size);
memory.copy(out, changetype<usize>(this) + offset, size);
return runtime.register<String>(out);
return gc.register<String>(out);
}
trimEnd(): String {
@ -275,9 +276,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
}
if (!size) return changetype<String>("");
if (size == originalSize) return this;
var out = runtime.allocRaw(size);
var out = runtime.alloc(size);
memory.copy(out, changetype<usize>(this), size);
return runtime.register<String>(out);
return gc.register<String>(out);
}
padStart(targetLength: i32, padString: string = " "): String {
@ -287,7 +288,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
var padSize = <usize>padString.length << 1;
if (targetSize < thisSize || !padSize) return this;
var prependSize = targetSize - thisSize;
var out = runtime.allocRaw(targetSize);
var out = runtime.alloc(targetSize);
if (prependSize > padSize) {
let repeatCount = (prependSize - 2) / padSize;
let restBase = repeatCount * padSize;
@ -298,7 +299,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
memory.copy(out, changetype<usize>(padString), prependSize);
}
memory.copy(out + prependSize, changetype<usize>(this), thisSize);
return runtime.register<String>(out);
return gc.register<String>(out);
}
padEnd(targetLength: i32, padString: string = " "): String {
@ -308,7 +309,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
var padSize = <usize>padString.length << 1;
if (targetSize < thisSize || !padSize) return this;
var appendSize = targetSize - thisSize;
var out = runtime.allocRaw(targetSize);
var out = runtime.alloc(targetSize);
memory.copy(out, changetype<usize>(this), thisSize);
if (appendSize > padSize) {
let repeatCount = (appendSize - 2) / padSize;
@ -319,7 +320,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
} else {
memory.copy(out + thisSize, changetype<usize>(padString), appendSize);
}
return runtime.register<String>(out);
return gc.register<String>(out);
}
repeat(count: i32 = 0): String {
@ -333,9 +334,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
if (count == 0 || !length) return changetype<String>("");
if (count == 1) return this;
var out = runtime.allocRaw((length * count) << 1);
var out = runtime.alloc((length * count) << 1);
memory.repeat(out, changetype<usize>(this), <usize>length << 1, count);
return runtime.register<String>(out);
return gc.register<String>(out);
}
slice(beginIndex: i32, endIndex: i32 = i32.MAX_VALUE): String {
@ -344,9 +345,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
var end = endIndex < 0 ? max(endIndex + len, 0) : min(endIndex, len);
len = end - begin;
if (len <= 0) return changetype<String>("");
var out = runtime.allocRaw(len << 1);
var out = runtime.alloc(len << 1);
memory.copy(out, changetype<usize>(this) + (<usize>begin << 1), <usize>len << 1);
return runtime.register<String>(out);
return gc.register<String>(out);
}
split(separator: String | null = null, limit: i32 = i32.MAX_VALUE): String[] {
@ -364,7 +365,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
let buffer = unreachable(); // TODO
// let buffer = <ArrayBuffer>result.buffer_;
for (let i: isize = 0; i < length; ++i) {
let char = runtime.allocRaw(2);
let char = runtime.alloc(2);
store<u16>(
changetype<usize>(char),
load<u16>(
@ -384,9 +385,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
while ((end = this.indexOf(separator!, start)) != -1) {
let len = end - start;
if (len > 0) {
let out = runtime.allocRaw(<usize>len << 1);
let out = runtime.alloc(<usize>len << 1);
memory.copy(out, changetype<usize>(this) + (<usize>start << 1), <usize>len << 1);
result.push(runtime.register<String>(out));
result.push(gc.register<String>(out));
} else {
result.push(changetype<String>(""));
}
@ -400,9 +401,9 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
}
var len = length - start;
if (len > 0) {
let out = runtime.allocRaw(<usize>len << 1);
let out = runtime.alloc(<usize>len << 1);
memory.copy(out, changetype<usize>(this) + (<usize>start << 1), <usize>len << 1);
result.push(runtime.register<String>(out));
result.push(gc.register<String>(out));
} else {
result.push(changetype<String>(""));
}
@ -474,10 +475,10 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
}
}
assert(ptrPos == len);
var out = runtime.allocRaw(bufPos);
var out = runtime.alloc(bufPos);
memory.copy(changetype<usize>(out), buf, bufPos);
memory.free(buf);
return runtime.register<string>(out);
return gc.register<string>(out);
}
toUTF8(): usize {

View File

@ -1,4 +1,5 @@
import { runtime, ArrayBufferView } from "./runtime";
import { gc } from "./gc";
import { COMPARATOR, SORT as SORT_IMPL } from "./util/sort";
function clampToByte(value: i32): i32 {
@ -759,11 +760,11 @@ function SUBARRAY<TArray extends ArrayBufferView, T>(
else begin = min(begin, length);
if (end < 0) end = max(length + end, begin);
else end = max(min(end, length), begin);
var out = runtime.allocRaw(offsetof<TArray>());
var out = runtime.alloc(offsetof<TArray>());
store<usize>(out, buffer, offsetof<TArray>("buffer"));
store<usize>(out, array.dataStart + (<usize>begin << alignof<T>()) , offsetof<TArray>("dataStart"));
store<usize>(out, array.dataStart + (<usize>begin << alignof<T>()) , offsetof<TArray>("dataStart"));
store<usize>(out, array.dataEnd + (<usize>(end - begin) << alignof<T>()), offsetof<TArray>("dataEnd"));
runtime.link(buffer, runtime.register<TArray>(out)); // register first, then link
gc.link(buffer, gc.register<TArray>(out)); // register first, then link
return changetype<TArray>(out);
}

View File

@ -1,4 +1,5 @@
import { runtime, ArrayBufferView } from "../runtime";
import { gc } from "../gc";
import { CharCode } from "./string";
// @ts-ignore: decorator
@ -265,7 +266,7 @@ export function utoa32(value: u32): String {
var out = runtime.alloc(decimals << 1);
utoa32_core(changetype<usize>(out), value, decimals);
return runtime.register<String>(out);
return gc.register<String>(out);
}
export function itoa32(value: i32): String {
@ -280,7 +281,7 @@ export function itoa32(value: i32): String {
utoa32_core(changetype<usize>(out), value, decimals);
if (sign) store<u16>(changetype<usize>(out), CharCode.MINUS);
return runtime.register<String>(out);
return gc.register<String>(out);
}
export function utoa64(value: u64): String {
@ -297,7 +298,7 @@ export function utoa64(value: u64): String {
out = runtime.alloc(decimals << 1);
utoa64_core(changetype<usize>(out), value, decimals);
}
return runtime.register<String>(out);
return gc.register<String>(out);
}
export function itoa64(value: i64): String {
@ -319,7 +320,7 @@ export function itoa64(value: i64): String {
}
if (sign) store<u16>(changetype<usize>(out), CharCode.MINUS);
return runtime.register<String>(out);
return gc.register<String>(out);
}
export function itoa<T extends number>(value: T): String {
@ -627,7 +628,7 @@ export function dtoa(value: f64): String {
var temp = runtime.alloc(MAX_DOUBLE_LENGTH << 1);
var length = dtoa_core(temp, value);
var result = changetype<String>(temp).substring(0, length);
runtime.free(temp);
runtime.freeUnregistered(temp);
return result;
}

View File

@ -1170,7 +1170,7 @@
local.get $0
call $~lib/allocator/tlsf/Root#use
)
(func $~lib/runtime/runtime.allocRaw (; 17 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/runtime/runtime.alloc (; 17 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
i32.const 1
i32.const 32
@ -1197,240 +1197,7 @@
i32.const 16
i32.add
)
(func $~lib/util/memory/memset (; 18 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32)
local.get $1
i32.eqz
if
return
end
local.get $0
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
i32.const 1
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 2
i32.le_u
if
return
end
local.get $0
i32.const 1
i32.add
i32.const 0
i32.store8
local.get $0
i32.const 2
i32.add
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 2
i32.sub
i32.const 0
i32.store8
local.get $2
i32.const 3
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 6
i32.le_u
if
return
end
local.get $0
i32.const 3
i32.add
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
i32.const 4
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 8
i32.le_u
if
return
end
i32.const 0
local.get $0
i32.sub
i32.const 3
i32.and
local.tee $2
local.get $0
i32.add
local.tee $0
i32.const 0
i32.store
local.get $1
local.get $2
i32.sub
i32.const -4
i32.and
local.tee $1
local.get $0
i32.add
i32.const 4
i32.sub
i32.const 0
i32.store
local.get $1
i32.const 8
i32.le_u
if
return
end
local.get $0
i32.const 4
i32.add
i32.const 0
i32.store
local.get $0
i32.const 8
i32.add
i32.const 0
i32.store
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 12
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 8
i32.sub
i32.const 0
i32.store
local.get $1
i32.const 24
i32.le_u
if
return
end
local.get $0
i32.const 12
i32.add
i32.const 0
i32.store
local.get $0
i32.const 16
i32.add
i32.const 0
i32.store
local.get $0
i32.const 20
i32.add
i32.const 0
i32.store
local.get $0
i32.const 24
i32.add
i32.const 0
i32.store
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 28
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 24
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 20
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 16
i32.sub
i32.const 0
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 0
i64.store
local.get $0
i32.const 8
i32.add
i64.const 0
i64.store
local.get $0
i32.const 16
i32.add
i64.const 0
i64.store
local.get $0
i32.const 24
i32.add
i64.const 0
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
)
(func $~lib/memory/memory.fill (; 19 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
local.get $0
local.get $1
call $~lib/util/memory/memset
)
(func $~lib/runtime/runtime.alloc (; 20 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
local.get $0
call $~lib/runtime/runtime.allocRaw
local.tee $1
local.get $0
call $~lib/memory/memory.fill
local.get $1
)
(func $~lib/util/memory/memcpy (; 21 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/util/memory/memcpy (; 18 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
@ -2327,7 +2094,7 @@
i32.store8
end
)
(func $~lib/util/memory/memmove (; 22 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/util/memory/memmove (; 19 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
local.get $0
@ -2525,7 +2292,231 @@
end
end
)
(func $~lib/allocator/tlsf/__memory_free (; 23 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/util/memory/memset (; 20 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32)
local.get $1
i32.eqz
if
return
end
local.get $0
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
i32.const 1
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 2
i32.le_u
if
return
end
local.get $0
i32.const 1
i32.add
i32.const 0
i32.store8
local.get $0
i32.const 2
i32.add
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 2
i32.sub
i32.const 0
i32.store8
local.get $2
i32.const 3
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 6
i32.le_u
if
return
end
local.get $0
i32.const 3
i32.add
i32.const 0
i32.store8
local.get $0
local.get $1
i32.add
i32.const 4
i32.sub
i32.const 0
i32.store8
local.get $1
i32.const 8
i32.le_u
if
return
end
i32.const 0
local.get $0
i32.sub
i32.const 3
i32.and
local.tee $2
local.get $0
i32.add
local.tee $0
i32.const 0
i32.store
local.get $1
local.get $2
i32.sub
i32.const -4
i32.and
local.tee $1
local.get $0
i32.add
i32.const 4
i32.sub
i32.const 0
i32.store
local.get $1
i32.const 8
i32.le_u
if
return
end
local.get $0
i32.const 4
i32.add
i32.const 0
i32.store
local.get $0
i32.const 8
i32.add
i32.const 0
i32.store
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 12
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 8
i32.sub
i32.const 0
i32.store
local.get $1
i32.const 24
i32.le_u
if
return
end
local.get $0
i32.const 12
i32.add
i32.const 0
i32.store
local.get $0
i32.const 16
i32.add
i32.const 0
i32.store
local.get $0
i32.const 20
i32.add
i32.const 0
i32.store
local.get $0
i32.const 24
i32.add
i32.const 0
i32.store
local.get $0
local.get $1
i32.add
local.tee $2
i32.const 28
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 24
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 20
i32.sub
i32.const 0
i32.store
local.get $2
i32.const 16
i32.sub
i32.const 0
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 0
i64.store
local.get $0
i32.const 8
i32.add
i64.const 0
i64.store
local.get $0
i32.const 16
i32.add
i64.const 0
i64.store
local.get $0
i32.const 24
i32.add
i64.const 0
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
)
(func $~lib/memory/memory.fill (; 21 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
local.get $0
local.get $1
call $~lib/util/memory/memset
)
(func $~lib/allocator/tlsf/__memory_free (; 22 ;) (type $FUNCSIG$vi) (param $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
@ -2563,7 +2554,7 @@
end
end
)
(func $~lib/runtime/runtime.realloc (; 24 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/runtime/runtime.realloc (; 23 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
@ -2604,7 +2595,8 @@
local.get $4
call $~lib/allocator/tlsf/__memory_allocate
local.tee $5
i32.const -1520547049
local.get $3
i32.load
i32.store
local.get $5
i32.const 0
@ -2637,7 +2629,7 @@
if
i32.const 0
i32.const 184
i32.const 96
i32.const 87
i32.const 10
call $~lib/env/abort
unreachable
@ -2667,14 +2659,14 @@
i32.store offset=4
local.get $0
)
(func $~lib/runtime/runtime.unref (; 25 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/runtime/runtime.unrefUnregistered (; 24 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
i32.const 232
i32.lt_u
if
i32.const 0
i32.const 184
i32.const 117
i32.const 111
i32.const 4
call $~lib/env/abort
unreachable
@ -2689,14 +2681,14 @@
if
i32.const 0
i32.const 184
i32.const 119
i32.const 113
i32.const 4
call $~lib/env/abort
unreachable
end
local.get $0
)
(func $start:std/runtime (; 26 ;) (type $FUNCSIG$v)
(func $start:std/runtime (; 25 ;) (type $FUNCSIG$v)
(local $0 i32)
(local $1 i32)
(local $2 i32)
@ -2924,7 +2916,7 @@
unreachable
end
global.get $std/runtime/ref2
call $~lib/runtime/runtime.unref
call $~lib/runtime/runtime.unrefUnregistered
call $~lib/allocator/tlsf/__memory_free
global.get $std/runtime/barrier2
call $~lib/runtime/runtime.alloc
@ -2945,7 +2937,7 @@
global.set $std/runtime/ref4
global.get $std/runtime/ref4
local.tee $0
call $~lib/runtime/runtime.unref
call $~lib/runtime/runtime.unrefUnregistered
i32.const 2
i32.store
local.get $0
@ -3023,10 +3015,10 @@
unreachable
end
)
(func $start (; 27 ;) (type $FUNCSIG$v)
(func $start (; 26 ;) (type $FUNCSIG$v)
call $start:std/runtime
)
(func $null (; 28 ;) (type $FUNCSIG$v)
(func $null (; 27 ;) (type $FUNCSIG$v)
nop
)
)

View File

@ -50,12 +50,12 @@ var ref2 = runtime.realloc(ref1, barrier2);
assert(ref1 != ref2); // moves
var header2 = changetype<runtime.Header>(ref2 - runtime.Header.SIZE);
assert(header2.payloadSize == barrier2);
runtime.free(ref2);
runtime.freeUnregistered(ref2);
var ref3 = runtime.alloc(barrier2);
assert(ref1 == ref3); // reuses space of ref1 (free'd in realloc), ref2 (explicitly free'd)
var ref4 = runtime.alloc(barrier1);
runtime.register<A>(ref4); // should call __REGISTER_IMPL
gc.register<A>(ref4); // should call __gc_register
assert(register_ref == ref4);
var header4 = changetype<runtime.Header>(register_ref - runtime.Header.SIZE);
assert(header4.classId == gc.classId<A>());

View File

@ -1466,7 +1466,7 @@
call $~lib/allocator/tlsf/__memory_allocate
return
)
(func $~lib/runtime/runtime.allocRaw (; 24 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/runtime/runtime.alloc (; 24 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
local.get $0
call $~lib/runtime/runtime.adjust
@ -1488,278 +1488,7 @@
i32.const 16
i32.add
)
(func $~lib/util/memory/memset (; 25 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i64)
local.get $2
i32.eqz
if
return
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
return
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
return
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
return
end
i32.const 0
local.get $0
i32.sub
i32.const 3
i32.and
local.set $3
local.get $0
local.get $3
i32.add
local.set $0
local.get $2
local.get $3
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
return
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
return
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 $3
local.get $0
local.get $3
i32.add
local.set $0
local.get $2
local.get $3
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 $5
block $break|0
loop $continue|0
local.get $2
i32.const 32
i32.ge_u
if
block
local.get $0
local.get $5
i64.store
local.get $0
i32.const 8
i32.add
local.get $5
i64.store
local.get $0
i32.const 16
i32.add
local.get $5
i64.store
local.get $0
i32.const 24
i32.add
local.get $5
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
)
(func $~lib/memory/memory.fill (; 26 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0
local.get $1
local.get $2
call $~lib/util/memory/memset
)
(func $~lib/runtime/runtime.alloc (; 27 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
local.get $0
call $~lib/runtime/runtime.allocRaw
local.set $1
local.get $1
i32.const 0
local.get $0
call $~lib/memory/memory.fill
local.get $1
)
(func $~lib/util/memory/memcpy (; 28 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/util/memory/memcpy (; 25 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
@ -2960,7 +2689,7 @@
i32.store8
end
)
(func $~lib/util/memory/memmove (; 29 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/util/memory/memmove (; 26 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
local.get $0
local.get $1
@ -3187,13 +2916,273 @@
end
end
)
(func $~lib/memory/memory.copy (; 30 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(func $~lib/memory/memory.copy (; 27 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0
local.get $1
local.get $2
call $~lib/util/memory/memmove
)
(func $~lib/allocator/tlsf/__memory_free (; 31 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/util/memory/memset (; 28 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i64)
local.get $2
i32.eqz
if
return
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
return
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
return
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
return
end
i32.const 0
local.get $0
i32.sub
i32.const 3
i32.and
local.set $3
local.get $0
local.get $3
i32.add
local.set $0
local.get $2
local.get $3
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
return
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
return
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 $3
local.get $0
local.get $3
i32.add
local.set $0
local.get $2
local.get $3
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 $5
block $break|0
loop $continue|0
local.get $2
i32.const 32
i32.ge_u
if
block
local.get $0
local.get $5
i64.store
local.get $0
i32.const 8
i32.add
local.get $5
i64.store
local.get $0
i32.const 16
i32.add
local.get $5
i64.store
local.get $0
i32.const 24
i32.add
local.get $5
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
)
(func $~lib/memory/memory.fill (; 29 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0
local.get $1
local.get $2
call $~lib/util/memory/memset
)
(func $~lib/allocator/tlsf/__memory_free (; 30 ;) (type $FUNCSIG$vi) (param $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
@ -3236,19 +3225,15 @@
end
end
)
(func $~lib/memory/memory.free (; 32 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/memory/memory.free (; 31 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
call $~lib/allocator/tlsf/__memory_free
)
(func $std/runtime/__gc_register (; 33 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $std/runtime/__gc_register (; 32 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
global.set $std/runtime/register_ref
)
(func $~lib/gc/gc.register (; 34 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
call $std/runtime/__gc_register
)
(func $~lib/runtime/runtime.realloc (; 35 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/runtime/runtime.realloc (; 33 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
@ -3282,7 +3267,8 @@
call $~lib/memory/memory.allocate
local.set $5
local.get $5
i32.const -1520547049
local.get $2
i32.load
i32.store
local.get $5
i32.const 0
@ -3318,7 +3304,7 @@
if
i32.const 0
i32.const 184
i32.const 96
i32.const 87
i32.const 10
call $~lib/env/abort
unreachable
@ -3327,7 +3313,7 @@
call $~lib/memory/memory.free
else
local.get $0
call $~lib/gc/gc.register
call $std/runtime/__gc_register
end
local.get $5
local.set $2
@ -3351,7 +3337,7 @@
i32.store offset=4
local.get $0
)
(func $~lib/runtime/runtime.unref (; 36 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/runtime/runtime.unrefUnregistered (; 34 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32)
local.get $0
global.get $~lib/memory/HEAP_BASE
@ -3362,7 +3348,7 @@
if
i32.const 0
i32.const 184
i32.const 117
i32.const 111
i32.const 4
call $~lib/env/abort
unreachable
@ -3379,25 +3365,25 @@
if
i32.const 0
i32.const 184
i32.const 119
i32.const 113
i32.const 4
call $~lib/env/abort
unreachable
end
local.get $1
)
(func $~lib/runtime/runtime.free<usize> (; 37 ;) (type $FUNCSIG$vi) (param $0 i32)
(func $~lib/runtime/runtime.freeUnregistered<usize> (; 35 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0
call $~lib/runtime/runtime.unref
call $~lib/runtime/runtime.unrefUnregistered
call $~lib/memory/memory.free
)
(func $~lib/arraybuffer/ArrayBuffer#get:byteLength (; 38 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/arraybuffer/ArrayBuffer#get:byteLength (; 36 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
i32.const 16
i32.sub
i32.load offset=4
)
(func $~lib/string/String#get:length (; 39 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(func $~lib/string/String#get:length (; 37 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
i32.const 16
i32.sub
@ -3405,7 +3391,7 @@
i32.const 1
i32.shr_u
)
(func $start:std/runtime (; 40 ;) (type $FUNCSIG$v)
(func $start:std/runtime (; 38 ;) (type $FUNCSIG$v)
(local $0 i32)
call $start:~lib/allocator/tlsf
i32.const 2
@ -3631,7 +3617,7 @@
unreachable
end
global.get $std/runtime/ref2
call $~lib/runtime/runtime.free<usize>
call $~lib/runtime/runtime.freeUnregistered<usize>
global.get $std/runtime/barrier2
call $~lib/runtime/runtime.alloc
global.set $std/runtime/ref3
@ -3650,15 +3636,15 @@
global.get $std/runtime/barrier1
call $~lib/runtime/runtime.alloc
global.set $std/runtime/ref4
block $~lib/runtime/runtime.register<A>|inlined.0 (result i32)
block $~lib/gc/gc.register<A>|inlined.0 (result i32)
global.get $std/runtime/ref4
local.set $0
local.get $0
call $~lib/runtime/runtime.unref
call $~lib/runtime/runtime.unrefUnregistered
i32.const 2
i32.store
local.get $0
call $~lib/gc/gc.register
call $std/runtime/__gc_register
local.get $0
end
drop
@ -3734,9 +3720,9 @@
unreachable
end
)
(func $start (; 41 ;) (type $FUNCSIG$v)
(func $start (; 39 ;) (type $FUNCSIG$v)
call $start:std/runtime
)
(func $null (; 42 ;) (type $FUNCSIG$v)
(func $null (; 40 ;) (type $FUNCSIG$v)
)
)