From f7ad5f85ca9f927853c0fc151dd9c387d1c01a05 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 27 Mar 2019 15:05:45 +0100 Subject: [PATCH] fixes --- src/compiler.ts | 7 + src/diagnosticMessages.generated.ts | 4 +- src/diagnosticMessages.json | 2 +- src/program.ts | 11 + std/assembly/memory.ts | 11 +- tests/allocators/arena/optimized.wat | 1420 ++++++++++- tests/allocators/arena/untouched.wat | 1815 +++++++++++-- tests/allocators/buddy/assembly/buddy.ts | 535 ++++ tests/allocators/buddy/assembly/index.ts | 2 +- tests/allocators/buddy/optimized.wat | 1656 ++++++++++-- tests/allocators/buddy/untouched.wat | 1936 ++++++++++++-- tests/allocators/tlsf/optimized.wat | 1537 +++++++++++- tests/allocators/tlsf/untouched.wat | 2234 ++++++++++++++--- tests/compiler/new-without-allocator.ts | 1 + .../new-without-allocator.untouched.wat | 107 - 15 files changed, 9983 insertions(+), 1295 deletions(-) create mode 100644 tests/allocators/buddy/assembly/buddy.ts diff --git a/src/compiler.ts b/src/compiler.ts index fc6b9555..04bf6e5b 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -8091,6 +8091,13 @@ export class Compiler extends DiagnosticEmitter { var options = this.options; var classType = classInstance.type; + if (!program.allocateMem) { + this.error( + DiagnosticCode.An_allocator_must_be_present_to_use_0, + reportNode.range, "new" + ); + } + if (classInstance.hasDecorator(DecoratorFlags.UNMANAGED)) { // memory.allocate(sizeof()) this.currentType = classType; diff --git a/src/diagnosticMessages.generated.ts b/src/diagnosticMessages.generated.ts index 9fc1e2e4..d678ac49 100644 --- a/src/diagnosticMessages.generated.ts +++ b/src/diagnosticMessages.generated.ts @@ -24,7 +24,7 @@ export enum DiagnosticCode { Class_0_is_sealed_and_cannot_be_extended = 211, Decorator_0_is_not_valid_here = 212, Duplicate_decorator = 213, - An_allocator_must_be_declared_to_allocate_memory_Try_importing_allocator_arena_or_allocator_tlsf = 214, + An_allocator_must_be_present_to_use_0 = 214, Optional_parameter_must_have_an_initializer = 215, Constructor_of_class_0_must_not_require_any_arguments = 216, Function_0_cannot_be_inlined_into_itself = 217, @@ -161,7 +161,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string { case 211: return "Class '{0}' is sealed and cannot be extended."; case 212: return "Decorator '{0}' is not valid here."; case 213: return "Duplicate decorator."; - case 214: return "An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf."; + case 214: return "An allocator must be present to use '{0}'."; case 215: return "Optional parameter must have an initializer."; case 216: return "Constructor of class '{0}' must not require any arguments."; case 217: return "Function '{0}' cannot be inlined into itself."; diff --git a/src/diagnosticMessages.json b/src/diagnosticMessages.json index 906e6712..6516c953 100644 --- a/src/diagnosticMessages.json +++ b/src/diagnosticMessages.json @@ -16,7 +16,7 @@ "Class '{0}' is sealed and cannot be extended.": 211, "Decorator '{0}' is not valid here.": 212, "Duplicate decorator.": 213, - "An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.": 214, + "An allocator must be present to use '{0}'.": 214, "Optional parameter must have an initializer.": 215, "Constructor of class '{0}' must not require any arguments.": 216, "Function '{0}' cannot be inlined into itself.": 217, diff --git a/src/program.ts b/src/program.ts index 9cff3fc7..f677e9a3 100644 --- a/src/program.ts +++ b/src/program.ts @@ -367,6 +367,8 @@ export class Program extends DiagnosticEmitter { /** Runtime make array function. `makeArray(capacity: i32, source: usize = 0, cid: u32): usize` */ makeArrayInstance: Function | null = null; + allocateMem: Function | null = null; + freeMem: Function | null = null; linkRef: Function | null = null; unlinkRef: Function | null = null; retainRef: Function | null = null; @@ -835,6 +837,15 @@ export class Program extends DiagnosticEmitter { assert(element.kind == ElementKind.FUNCTION_PROTOTYPE); this.makeArrayInstance = this.resolver.resolveFunction(element, null); } + // memory allocator interface + if (element = this.lookupGlobal("__memory_allocate")) { + assert(element.kind == ElementKind.FUNCTION_PROTOTYPE); + this.allocateMem = this.resolver.resolveFunction(element, null); + element = assert(this.lookupGlobal("__memory_free")); + assert(element.kind == ElementKind.FUNCTION_PROTOTYPE); + this.freeMem = this.resolver.resolveFunction(element, null); + } + // garbage collector interface if (this.lookupGlobal("__ref_collect")) { if (element = this.lookupGlobal("__ref_link")) { assert(element.kind == ElementKind.FUNCTION_PROTOTYPE); diff --git a/std/assembly/memory.ts b/std/assembly/memory.ts index 190e995f..3e86001f 100644 --- a/std/assembly/memory.ts +++ b/std/assembly/memory.ts @@ -35,14 +35,14 @@ export namespace memory { // @ts-ignore: decorator @unsafe export function init(segmentIndex: u32, srcOffset: usize, dstOffset: usize, n: usize): void { - ERROR("not implemented"); + unreachable(); // not yet implemented } /** Drops a memory segment. */ // @ts-ignore: decorator @unsafe export function drop(segmentIndex: u32): void { - ERROR("not implemented"); + unreachable(); // not yet implemented } /** Dynamically allocates a section of memory and returns its address. */ @@ -51,8 +51,7 @@ export namespace memory { export function allocate(size: usize): usize { // @ts-ignore: stub if (isDefined(__memory_allocate)) return __memory_allocate(size); - else WARNING("missing implementation: memory.allocate"); - return unreachable(); + else return unreachable(); } /** Dynamically frees a section of memory by the previously allocated address. */ @@ -61,7 +60,7 @@ export namespace memory { export function free(ptr: usize): void { // @ts-ignore: stub if (isDefined(__memory_free)) __memory_free(ptr); - else WARNING("missing implementation: memory.free"); + else unreachable(); } /** Resets the memory to its initial state. Arena allocator only. */ @@ -70,7 +69,7 @@ export namespace memory { export function reset(): void { // @ts-ignore: stub if (isDefined(__memory_reset)) __memory_reset(); - else WARNING("missing implementation: memory.reset"); + else unreachable(); } /** Repeats a section of memory at a specific address. */ diff --git a/tests/allocators/arena/optimized.wat b/tests/allocators/arena/optimized.wat index 0756cb69..b4b341e5 100644 --- a/tests/allocators/arena/optimized.wat +++ b/tests/allocators/arena/optimized.wat @@ -1,8 +1,10 @@ (module - (type $_ (func)) - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $i_ (func (param i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (memory $0 0) (table $0 1 funcref) (elem (i32.const 0) $null) @@ -10,68 +12,22 @@ (global $~lib/allocator/arena/offset (mut i32) (i32.const 0)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) (start $start) - (func $~lib/internal/memory/memcmp (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - br $continue|0 - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end + (func $~lib/memory/memory.init (; 0 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable ) - (func $~lib/memory/memory.compare (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp + (func $~lib/memory/memory.drop (; 1 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable ) - (func $~lib/allocator/arena/__memory_allocate (; 2 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/memory/memory.allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -96,7 +52,7 @@ i32.add i32.const -8 i32.and - local.tee $3 + local.tee $0 current_memory local.tee $1 i32.const 16 @@ -104,7 +60,7 @@ i32.gt_u if local.get $1 - local.get $3 + local.get $0 local.get $2 i32.sub i32.const 65535 @@ -113,7 +69,7 @@ i32.and i32.const 16 i32.shr_u - local.tee $0 + local.tee $3 local.tee $4 local.get $1 local.get $4 @@ -123,7 +79,7 @@ i32.const 0 i32.lt_s if - local.get $0 + local.get $3 grow_memory i32.const 0 i32.lt_s @@ -132,28 +88,1346 @@ end end end - local.get $3 + local.get $0 global.set $~lib/allocator/arena/offset local.get $2 ) - (func $~lib/memory/memory.allocate (; 3 ;) (type $ii) (param $0 i32) (result i32) - local.get $0 - call $~lib/allocator/arena/__memory_allocate - ) - (func $~lib/memory/memory.free (; 4 ;) (type $i_) (param $0 i32) + (func $~lib/memory/memory.free (; 3 ;) (type $FUNCSIG$vi) (param $0 i32) nop ) - (func $~lib/memory/memory.reset (; 5 ;) (type $_) + (func $~lib/memory/memory.reset (; 4 ;) (type $FUNCSIG$v) global.get $~lib/allocator/arena/startOffset global.set $~lib/allocator/arena/offset ) - (func $start (; 6 ;) (type $_) + (func $~lib/util/memory/memcpy (; 5 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + loop $continue|0 + local.get $1 + i32.const 3 + i32.and + local.get $2 + local.get $2 + select + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|0 + end + end + local.get $0 + i32.const 3 + i32.and + i32.eqz + if + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|1 + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $1 + i32.const 8 + i32.add + local.set $1 + local.get $0 + i32.const 8 + i32.add + local.set $0 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $1 + i32.const 4 + i32.add + local.set $1 + local.get $0 + i32.const 4 + i32.add + local.set $0 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $1 + i32.const 2 + i32.add + local.set $1 + local.get $0 + i32.const 2 + i32.add + local.set $0 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + i32.const 1 + i32.sub + br_table $case0|2 $case1|2 $case2|2 $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 1 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 5 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 9 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 13 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|3 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 2 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 6 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 10 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 14 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|4 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 3 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 7 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 11 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 15 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|5 + end + end + end + end + local.get $2 + i32.const 16 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + ) + (func $~lib/memory/memory.copy (; 6 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + br_if $~lib/util/memory/memmove|inlined.0 + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $3 + if (result i32) + local.get $3 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + br $continue|0 + end + end + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + br $continue|1 + end + end + end + loop $continue|2 + local.get $2 + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|2 + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|3 + end + end + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $2 + i32.const 8 + i32.sub + local.tee $2 + local.get $0 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + br $continue|4 + end + end + end + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 7 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + local.get $2 + local.get $3 + i32.mul + local.set $3 + loop $continue|0 + local.get $4 + local.get $3 + i32.lt_u + if + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $2 + local.get $4 + i32.add + local.set $4 + br $continue|0 + end + end + ) + (func $~lib/memory/memory.compare (; 8 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + local.get $0 + local.get $1 + i32.eq + if (result i32) + i32.const 0 + else + loop $continue|0 + local.get $2 + i32.const 0 + i32.ne + local.tee $3 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.eq + else + local.get $3 + end + if + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + i32.const 1 + i32.add + local.set $0 + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $continue|0 + end + end + local.get $2 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $start (; 9 ;) (type $FUNCSIG$v) i32.const 8 global.set $~lib/allocator/arena/startOffset global.get $~lib/allocator/arena/startOffset global.set $~lib/allocator/arena/offset ) - (func $null (; 7 ;) (type $_) + (func $null (; 10 ;) (type $FUNCSIG$v) nop ) ) diff --git a/tests/allocators/arena/untouched.wat b/tests/allocators/arena/untouched.wat index 66464937..47f9113f 100644 --- a/tests/allocators/arena/untouched.wat +++ b/tests/allocators/arena/untouched.wat @@ -1,8 +1,10 @@ (module - (type $_ (func)) - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $i_ (func (param i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (memory $0 0) (table $0 1 funcref) (elem (i32.const 0) $null) @@ -11,12 +13,1645 @@ (global $~lib/memory/HEAP_BASE i32 (i32.const 8)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) (start $start) - (func $start:~lib/allocator/arena (; 0 ;) (type $_) + (func $~lib/memory/memory.init (; 0 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable + ) + (func $~lib/memory/memory.drop (; 1 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable + ) + (func $~lib/memory/memory.allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + block $~lib/allocator/arena/__memory_allocate|inlined.0 (result i32) + local.get $0 + local.set $1 + local.get $1 + i32.const 1073741824 + i32.gt_u + if + unreachable + end + global.get $~lib/allocator/arena/offset + local.set $2 + local.get $2 + local.get $1 + local.tee $3 + i32.const 1 + local.tee $4 + local.get $3 + local.get $4 + i32.gt_u + select + i32.add + i32.const 7 + i32.add + i32.const 7 + i32.const -1 + i32.xor + i32.and + local.set $3 + current_memory + local.set $4 + local.get $3 + local.get $4 + i32.const 16 + i32.shl + i32.gt_u + if + local.get $3 + local.get $2 + i32.sub + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $5 + local.get $4 + local.tee $6 + local.get $5 + local.tee $7 + local.get $6 + local.get $7 + i32.gt_s + select + local.set $6 + local.get $6 + grow_memory + i32.const 0 + i32.lt_s + if + local.get $5 + grow_memory + i32.const 0 + i32.lt_s + if + unreachable + end + end + end + local.get $3 + global.set $~lib/allocator/arena/offset + local.get $2 + end + return + ) + (func $~lib/memory/memory.free (; 3 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + local.get $0 + local.set $1 + ) + (func $~lib/memory/memory.reset (; 4 ;) (type $FUNCSIG$v) + global.get $~lib/allocator/arena/startOffset + global.set $~lib/allocator/arena/offset + ) + (func $~lib/util/memory/memcpy (; 5 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $break|0 + loop $continue|0 + local.get $2 + if (result i32) + local.get $1 + i32.const 3 + i32.and + else + local.get $2 + end + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|0 + end + end + end + local.get $0 + i32.const 3 + i32.and + i32.const 0 + i32.eq + if + block $break|1 + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + block + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|1 + end + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.set $0 + local.get $1 + i32.const 4 + i32.add + local.set $1 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $0 + i32.const 2 + i32.add + local.set $0 + local.get $1 + i32.const 2 + i32.add + local.set $1 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + local.set $5 + local.get $5 + i32.const 1 + i32.eq + br_if $case0|2 + local.get $5 + i32.const 2 + i32.eq + br_if $case1|2 + local.get $5 + i32.const 3 + i32.eq + br_if $case2|2 + br $break|2 + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + block $break|3 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + block + local.get $1 + i32.const 1 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 5 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 9 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 13 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|3 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + block $break|4 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + block + local.get $1 + i32.const 2 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 6 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 10 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 14 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|4 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block $break|5 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + block + local.get $1 + i32.const 3 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 7 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 11 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 15 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|5 + end + end + end + br $break|2 + unreachable + end + unreachable + end + end + local.get $2 + i32.const 16 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 8 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + ) + (func $~lib/memory/memory.copy (; 6 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $5 + if (result i32) + local.get $5 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|0 + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + br $continue|0 + end + end + end + block $break|1 + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + br $continue|1 + end + end + end + end + block $break|2 + loop $continue|2 + local.get $2 + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|2 + end + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|3 + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + end + br $continue|3 + end + end + end + block $break|4 + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + local.get $2 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + end + br $continue|4 + end + end + end + end + block $break|5 + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 7 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + i32.const 0 + local.set $4 + local.get $2 + local.get $3 + i32.mul + local.set $5 + block $break|0 + loop $continue|0 + local.get $4 + local.get $5 + i32.lt_u + if + block + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $4 + local.get $2 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + ) + (func $~lib/memory/memory.compare (; 8 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + block $~lib/util/memory/memcmp|inlined.0 (result i32) + local.get $0 + local.set $5 + local.get $1 + local.set $4 + local.get $2 + local.set $3 + local.get $5 + local.get $4 + i32.eq + if + i32.const 0 + br $~lib/util/memory/memcmp|inlined.0 + end + block $break|0 + loop $continue|0 + local.get $3 + i32.const 0 + i32.ne + local.tee $6 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.eq + else + local.get $6 + end + if + block + local.get $3 + i32.const 1 + i32.sub + local.set $3 + local.get $5 + i32.const 1 + i32.add + local.set $5 + local.get $4 + i32.const 1 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + local.get $3 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $start (; 9 ;) (type $FUNCSIG$v) global.get $~lib/memory/HEAP_BASE i32.const 7 i32.add @@ -28,172 +1663,6 @@ global.get $~lib/allocator/arena/startOffset global.set $~lib/allocator/arena/offset ) - (func $start:assembly/index (; 1 ;) (type $_) - call $start:~lib/allocator/arena - ) - (func $~lib/internal/memory/memcmp (; 2 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - block $break|0 - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - block - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - end - br $continue|0 - end - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end - ) - (func $~lib/memory/memory.compare (; 3 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp - ) - (func $~lib/allocator/arena/__memory_allocate (; 4 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - local.get $0 - i32.const 1073741824 - i32.gt_u - if - unreachable - end - global.get $~lib/allocator/arena/offset - local.set $1 - local.get $1 - local.get $0 - local.tee $2 - i32.const 1 - local.tee $3 - local.get $2 - local.get $3 - i32.gt_u - select - i32.add - i32.const 7 - i32.add - i32.const 7 - i32.const -1 - i32.xor - i32.and - local.set $4 - current_memory - local.set $5 - local.get $4 - local.get $5 - i32.const 16 - i32.shl - i32.gt_u - if - local.get $4 - local.get $1 - i32.sub - i32.const 65535 - i32.add - i32.const 65535 - i32.const -1 - i32.xor - i32.and - i32.const 16 - i32.shr_u - local.set $2 - local.get $5 - local.tee $3 - local.get $2 - local.tee $6 - local.get $3 - local.get $6 - i32.gt_s - select - local.set $3 - local.get $3 - grow_memory - i32.const 0 - i32.lt_s - if - local.get $2 - grow_memory - i32.const 0 - i32.lt_s - if - unreachable - end - end - end - local.get $4 - global.set $~lib/allocator/arena/offset - local.get $1 - ) - (func $~lib/memory/memory.allocate (; 5 ;) (type $ii) (param $0 i32) (result i32) - local.get $0 - call $~lib/allocator/arena/__memory_allocate - return - ) - (func $~lib/allocator/arena/__memory_free (; 6 ;) (type $i_) (param $0 i32) - nop - ) - (func $~lib/memory/memory.free (; 7 ;) (type $i_) (param $0 i32) - local.get $0 - call $~lib/allocator/arena/__memory_free - return - ) - (func $~lib/allocator/arena/__memory_reset (; 8 ;) (type $_) - global.get $~lib/allocator/arena/startOffset - global.set $~lib/allocator/arena/offset - ) - (func $~lib/memory/memory.reset (; 9 ;) (type $_) - call $~lib/allocator/arena/__memory_reset - return - ) - (func $start (; 10 ;) (type $_) - call $start:assembly/index - ) - (func $null (; 11 ;) (type $_) + (func $null (; 10 ;) (type $FUNCSIG$v) ) ) diff --git a/tests/allocators/buddy/assembly/buddy.ts b/tests/allocators/buddy/assembly/buddy.ts new file mode 100644 index 00000000..88c1a104 --- /dev/null +++ b/tests/allocators/buddy/assembly/buddy.ts @@ -0,0 +1,535 @@ +/* + Copyright 2018 Evan Wallace + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/// see: https://github.com/evanw/buddy-malloc + +/* + * This file implements a buddy memory allocator, which is an allocator that + * allocates memory within a fixed linear address range. It spans the address + * range with a binary tree that tracks free space. Both "malloc" and "free" + * are O(log N) time where N is the maximum possible number of allocations. + * + * The "buddy" term comes from how the tree is used. When memory is allocated, + * nodes in the tree are split recursively until a node of the appropriate size + * is reached. Every split results in two child nodes, each of which is the + * buddy of the other. When a node is freed, the node and its buddy can be + * merged again if the buddy is also free. This makes the memory available + * for larger allocations again. + */ + +/* + * Every allocation needs an 8-byte header to store the allocation size while + * staying 8-byte aligned. The address returned by "malloc" is the address + * right after this header (i.e. the size occupies the 8 bytes before the + * returned address). + */ +const HEADER_SIZE: usize = 8; + +/* + * The minimum allocation size is 16 bytes because we have an 8-byte header and + * we need to stay 8-byte aligned. + */ +const MIN_ALLOC_LOG2: usize = 4; +const MIN_ALLOC: usize = 1 << MIN_ALLOC_LOG2; + +/* + * The maximum allocation size is currently set to 2gb. This is the total size + * of the heap. It's technically also the maximum allocation size because the + * heap could consist of a single allocation of this size. But of course real + * heaps will have multiple allocations, so the real maximum allocation limit + * is at most 1gb. + */ +const MAX_ALLOC_LOG2: usize = 30; // 31; +const MAX_ALLOC: usize = 1 << MAX_ALLOC_LOG2; + +/* + * Allocations are done in powers of two starting from MIN_ALLOC and ending at + * MAX_ALLOC inclusive. Each allocation size has a bucket that stores the free + * list for that allocation size. + * + * Given a bucket index, the size of the allocations in that bucket can be + * found with "(size_t)1 << (MAX_ALLOC_LOG2 - bucket)". + */ +const BUCKET_COUNT: usize = MAX_ALLOC_LOG2 - MIN_ALLOC_LOG2 + 1; + +/* + * Free lists are stored as circular doubly-linked lists. Every possible + * allocation size has an associated free list that is threaded through all + * currently free blocks of that size. That means MIN_ALLOC must be at least + * "sizeof(list_t)". MIN_ALLOC is currently 16 bytes, so this will be true for + * both 32-bit and 64-bit. + */ +@unmanaged +class List { + prev: List; + next: List; + static readonly SIZE: usize = 2 * sizeof(); +} + +/* + * Each bucket corresponds to a certain allocation size and stores a free list + * for that size. The bucket at index 0 corresponds to an allocation size of + * MAX_ALLOC (i.e. the whole address space). + */ +var BUCKETS_START: usize = HEAP_BASE; +var BUCKETS_END: usize = BUCKETS_START + BUCKET_COUNT * List.SIZE; + +function buckets$get(index: usize): List { + assert(index < BUCKET_COUNT); + return changetype(BUCKETS_START + index * List.SIZE); +} + +/* + * We could initialize the allocator by giving it one free block the size of + * the entire address space. However, this would cause us to instantly reserve + * half of the entire address space on the first allocation, since the first + * split would store a free list entry at the start of the right child of the + * root. Instead, we have the tree start out small and grow the size of the + * tree as we use more memory. The size of the tree is tracked by this value. + */ +var bucket_limit: usize; + +/* + * This array represents a linearized binary tree of bits. Every possible + * allocation larger than MIN_ALLOC has a node in this tree (and therefore a + * bit in this array). + * + * Given the index for a node, lineraized binary trees allow you to traverse to + * the parent node or the child nodes just by doing simple arithmetic on the + * index: + * + * - Move to parent: index = (index - 1) / 2; + * - Move to left child: index = index * 2 + 1; + * - Move to right child: index = index * 2 + 2; + * - Move to sibling: index = ((index - 1) ^ 1) + 1; + * + * Each node in this tree can be in one of several states: + * + * - UNUSED (both children are UNUSED) + * - SPLIT (one child is UNUSED and the other child isn't) + * - USED (neither children are UNUSED) + * + * These states take two bits to store. However, it turns out we have enough + * information to distinguish between UNUSED and USED from context, so we only + * need to store SPLIT or not, which only takes a single bit. + * + * Note that we don't need to store any nodes for allocations of size MIN_ALLOC + * since we only ever care about parent nodes. + */ +const SPLIT_COUNT: usize = (1 << (BUCKET_COUNT - 1)) / 8; +var NODE_IS_SPLIT_START: usize = BUCKETS_END; +var NODE_IS_SPLIT_END: usize = NODE_IS_SPLIT_START + SPLIT_COUNT * sizeof(); + +function node_is_split$get(index: usize): i32 { + assert(index < SPLIT_COUNT); + return load(NODE_IS_SPLIT_START + index); +} + +function node_is_split$set(index: usize, state: i32): void { + assert(index < SPLIT_COUNT); + store(NODE_IS_SPLIT_START + index, state); +} + +/* + * This is the starting address of the address range for this allocator. Every + * returned allocation will be an offset of this pointer from 0 to MAX_ALLOC. + */ +var base_ptr: usize; + +/* + * This is the maximum address that has ever been used by the allocator. It's + * used to know when to call "brk" to request more memory from the kernel. + */ +var max_ptr: usize; + +/* + * Make sure all addresses before "new_value" are valid and can be used. Memory + * is allocated in a 2gb address range but that memory is not reserved up + * front. It's only reserved when it's needed by calling this function. This + * will return false if the memory could not be reserved. + */ +function update_max_ptr(new_value: usize): i32 { + if (new_value > max_ptr) { + // if (brk(new_value)) { + // return 0; + // } + let oldPages = memory.size(); + let newPages = (((new_value + 0xffff) & ~0xffff) >>> 16); + assert(newPages > oldPages); + if (memory.grow(newPages - oldPages) < 0) { + return 0; + } + // max_ptr = new_value; + max_ptr = newPages << 16; + } + return 1; +} + +/* + * Initialize a list to empty. Because these are circular lists, an "empty" + * list is an entry where both links point to itself. This makes insertion + * and removal simpler because they don't need any branches. + */ +function list_init(list: List): void { + list.prev = list; + list.next = list; +} + +/* + * Append the provided entry to the end of the list. This assumes the entry + * isn't in a list already because it overwrites the linked list pointers. + */ +function list_push(list: List, entry: List): void { + var prev = list.prev; + entry.prev = prev; + entry.next = list; + prev.next = entry; + list.prev = entry; +} + +/* + * Remove the provided entry from whichever list it's currently in. This + * assumes that the entry is in a list. You don't need to provide the list + * because the lists are circular, so the list's pointers will automatically + * be updated if the first or last entries are removed. + */ +function list_remove(entry: List): void { + var prev = entry.prev; + var next = entry.next; + prev.next = next; + next.prev = prev; +} + +/* + * Remove and return the first entry in the list or NULL if the list is empty. + */ +function list_pop(list: List): List | null { + var back = list.prev; + if (back == list) return null; + list_remove(back); + return back; +} + +/* + * This maps from the index of a node to the address of memory that node + * represents. The bucket can be derived from the index using a loop but is + * required to be provided here since having them means we can avoid the loop + * and have this function return in constant time. + */ +function ptr_for_node(index: usize, bucket: usize): usize { + return base_ptr + ((index - (1 << bucket) + 1) << (MAX_ALLOC_LOG2 - bucket)); +} + +/* + * This maps from an address of memory to the node that represents that + * address. There are often many nodes that all map to the same address, so + * the bucket is needed to uniquely identify a node. + */ +function node_for_ptr(ptr: usize, bucket: usize): usize { + return ((ptr - base_ptr) >> (MAX_ALLOC_LOG2 - bucket)) + (1 << bucket) - 1; +} + +/* + * Given the index of a node, this returns the "is split" flag of the parent. + */ +function parent_is_split(index: usize): bool { + index = (index - 1) / 2; + return ((node_is_split$get(index / 8) >>> (index % 8)) & 1) == 1; +} + +/* + * Given the index of a node, this flips the "is split" flag of the parent. + */ +function flip_parent_is_split(index: usize): void { + index = (index - 1) / 2; + var indexDiv8 = index / 8; + node_is_split$set(indexDiv8, + node_is_split$get(indexDiv8) ^ (1 << (index % 8)) + ); +} + +/* + * Given the requested size passed to "malloc", this function returns the index + * of the smallest bucket that can fit that size. + */ +function bucket_for_request(request: usize): usize { + var bucket = BUCKET_COUNT - 1; + var size = MIN_ALLOC; + + while (size < request) { + bucket--; + size *= 2; + } + + return bucket; +} + +/* + * The tree is always rooted at the current bucket limit. This call grows the + * tree by repeatedly doubling it in size until the root lies at the provided + * bucket index. Each doubling lowers the bucket limit by 1. + */ +function lower_bucket_limit(bucket: usize): u32 { + while (bucket < bucket_limit) { + let root = node_for_ptr(base_ptr, bucket_limit); + let right_child: usize; + + /* + * If the parent isn't SPLIT, that means the node at the current bucket + * limit is UNUSED and our address space is entirely free. In that case, + * clear the root free list, increase the bucket limit, and add a single + * block with the newly-expanded address space to the new root free list. + */ + if (!parent_is_split(root)) { + list_remove(changetype(base_ptr)); + list_init(buckets$get(--bucket_limit)); + list_push(buckets$get(bucket_limit), changetype(base_ptr)); + continue; + } + + /* + * Otherwise, the tree is currently in use. Create a parent node for the + * current root node in the SPLIT state with a right child on the free + * list. Make sure to reserve the memory for the free list entry before + * writing to it. Note that we do not need to flip the "is split" flag for + * our current parent because it's already on (we know because we just + * checked it above). + */ + right_child = ptr_for_node(root + 1, bucket_limit); + if (!update_max_ptr(right_child + List.SIZE)) { + return 0; + } + list_push(buckets$get(bucket_limit), changetype(right_child)); + list_init(buckets$get(--bucket_limit)); + + /* + * Set the grandparent's SPLIT flag so if we need to lower the bucket limit + * again, we'll know that the new root node we just added is in use. + */ + root = (root - 1) / 2; + if (root != 0) { + flip_parent_is_split(root); + } + } + + return 1; +} + +// Memory allocator interface + +@global export function __memory_allocate(request: usize): usize { + var original_bucket: usize, bucket: usize; + + /* + * Make sure it's possible for an allocation of this size to succeed. There's + * a hard-coded limit on the maximum allocation size because of the way this + * allocator works. + */ + if (request > MAX_ALLOC - HEADER_SIZE) unreachable(); + + /* + * Initialize our global state if this is the first call to "malloc". At the + * beginning, the tree has a single node that represents the smallest + * possible allocation size. More memory will be reserved later as needed. + */ + if (base_ptr == 0) { + // base_ptr = max_ptr = (uint8_t *)sbrk(0); + base_ptr = (NODE_IS_SPLIT_END + 7) & ~7; // must be aligned + max_ptr = memory.size() << 16; // must grow first + bucket_limit = BUCKET_COUNT - 1; + if (!update_max_ptr(base_ptr + List.SIZE)) { + return 0; + } + list_init(buckets$get(BUCKET_COUNT - 1)); + list_push(buckets$get(BUCKET_COUNT - 1), changetype(base_ptr)); + } + + /* + * Find the smallest bucket that will fit this request. This doesn't check + * that there's space for the request yet. + */ + bucket = bucket_for_request(request + HEADER_SIZE); + original_bucket = bucket; + + /* + * Search for a bucket with a non-empty free list that's as large or larger + * than what we need. If there isn't an exact match, we'll need to split a + * larger one to get a match. + */ + while (bucket + 1 != 0) { + let size: usize, bytes_needed: usize, i: usize; + let ptr: usize; + + /* + * We may need to grow the tree to be able to fit an allocation of this + * size. Try to grow the tree and stop here if we can't. + */ + if (!lower_bucket_limit(bucket)) { + return 0; + } + + /* + * Try to pop a block off the free list for this bucket. If the free list + * is empty, we're going to have to split a larger block instead. + */ + ptr = changetype(list_pop(buckets$get(bucket))); + if (!ptr) { + /* + * If we're not at the root of the tree or it's impossible to grow the + * tree any more, continue on to the next bucket. + */ + if (bucket != bucket_limit || bucket == 0) { + bucket--; + continue; + } + + /* + * Otherwise, grow the tree one more level and then pop a block off the + * free list again. Since we know the root of the tree is used (because + * the free list was empty), this will add a parent above this node in + * the SPLIT state and then add the new right child node to the free list + * for this bucket. Popping the free list will give us this right child. + */ + if (!lower_bucket_limit(bucket - 1)) { + return 0; + } + ptr = changetype(list_pop(buckets$get(bucket))); + } + + /* + * Try to expand the address space first before going any further. If we + * have run out of space, put this block back on the free list and fail. + */ + size = 1 << (MAX_ALLOC_LOG2 - bucket); + bytes_needed = bucket < original_bucket ? size / 2 + List.SIZE : size; + if (!update_max_ptr(ptr + bytes_needed)) { + list_push(buckets$get(bucket), changetype(ptr)); + return 0; + } + + /* + * If we got a node off the free list, change the node from UNUSED to USED. + * This involves flipping our parent's "is split" bit because that bit is + * the exclusive-or of the UNUSED flags of both children, and our UNUSED + * flag (which isn't ever stored explicitly) has just changed. + * + * Note that we shouldn't ever need to flip the "is split" bit of our + * grandparent because we know our buddy is USED so it's impossible for our + * grandparent to be UNUSED (if our buddy chunk was UNUSED, our parent + * wouldn't ever have been split in the first place). + */ + i = node_for_ptr(ptr, bucket); + if (i != 0) { + flip_parent_is_split(i); + } + + /* + * If the node we got is larger than we need, split it down to the correct + * size and put the new unused child nodes on the free list in the + * corresponding bucket. This is done by repeatedly moving to the left + * child, splitting the parent, and then adding the right child to the free + * list. + */ + while (bucket < original_bucket) { + i = i * 2 + 1; + bucket++; + flip_parent_is_split(i); + list_push( + buckets$get(bucket), + changetype(ptr_for_node(i + 1, bucket)) + ); + } + + /* + * Now that we have a memory address, write the block header (just the size + * of the allocation) and return the address immediately after the header. + */ + store(ptr, request); + return ptr + HEADER_SIZE; + } + + return 0; +} + +@global export function __memory_free(ptr: usize): void { + var bucket: usize, i: usize; + + /* + * Ignore any attempts to free a NULL pointer. + */ + if (!ptr) { + return; + } + + /* + * We were given the address returned by "malloc" so get back to the actual + * address of the node by subtracting off the size of the block header. Then + * look up the index of the node corresponding to this address. + */ + ptr = ptr - HEADER_SIZE; + bucket = bucket_for_request(load(ptr) + HEADER_SIZE); + i = node_for_ptr(ptr, bucket); + + /* + * Traverse up to the root node, flipping USED blocks to UNUSED and merging + * UNUSED buddies together into a single UNUSED parent. + */ + while (i != 0) { + /* + * Change this node from UNUSED to USED. This involves flipping our + * parent's "is split" bit because that bit is the exclusive-or of the + * UNUSED flags of both children, and our UNUSED flag (which isn't ever + * stored explicitly) has just changed. + */ + flip_parent_is_split(i); + + /* + * If the parent is now SPLIT, that means our buddy is USED, so don't merge + * with it. Instead, stop the iteration here and add ourselves to the free + * list for our bucket. + * + * Also stop here if we're at the current root node, even if that root node + * is now UNUSED. Root nodes don't have a buddy so we can't merge with one. + */ + if (parent_is_split(i) || bucket == bucket_limit) { + break; + } + + /* + * If we get here, we know our buddy is UNUSED. In this case we should + * merge with that buddy and continue traversing up to the root node. We + * need to remove the buddy from its free list here but we don't need to + * add the merged parent to its free list yet. That will be done once after + * this loop is finished. + */ + list_remove(changetype(ptr_for_node(((i - 1) ^ 1) + 1, bucket))); + i = (i - 1) / 2; + bucket--; + } + + /* + * Add ourselves to the free list for our bucket. We add to the back of the + * list because "malloc" takes from the back of the list and we want a "free" + * followed by a "malloc" of the same size to ideally use the same address + * for better memory locality. + */ + list_push(buckets$get(bucket), changetype(ptr_for_node(i, bucket))); +} diff --git a/tests/allocators/buddy/assembly/index.ts b/tests/allocators/buddy/assembly/index.ts index 2fe5eda0..b850ffb0 100644 --- a/tests/allocators/buddy/assembly/index.ts +++ b/tests/allocators/buddy/assembly/index.ts @@ -1,2 +1,2 @@ -import "allocator/buddy"; +import "./buddy"; export { memory }; diff --git a/tests/allocators/buddy/optimized.wat b/tests/allocators/buddy/optimized.wat index 234ec45d..4624ce82 100644 --- a/tests/allocators/buddy/optimized.wat +++ b/tests/allocators/buddy/optimized.wat @@ -1,87 +1,42 @@ (module - (type $_ (func)) - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $i_ (func (param i32))) - (type $ii_ (func (param i32 i32))) - (type $iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result 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$iiii (func (param i32 i32 i32) (result i32))) (memory $0 0) (table $0 1 funcref) (elem (i32.const 0) $null) - (global $~lib/allocator/buddy/BUCKETS_START (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/BUCKETS_END (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/bucket_limit (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/NODE_IS_SPLIT_START (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/NODE_IS_SPLIT_END (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/base_ptr (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/max_ptr (mut i32) (i32.const 0)) + (global $assembly/buddy/BUCKETS_START (mut i32) (i32.const 0)) + (global $assembly/buddy/BUCKETS_END (mut i32) (i32.const 0)) + (global $assembly/buddy/bucket_limit (mut i32) (i32.const 0)) + (global $assembly/buddy/NODE_IS_SPLIT_START (mut i32) (i32.const 0)) + (global $assembly/buddy/NODE_IS_SPLIT_END (mut i32) (i32.const 0)) + (global $assembly/buddy/base_ptr (mut i32) (i32.const 0)) + (global $assembly/buddy/max_ptr (mut i32) (i32.const 0)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) (start $start) - (func $~lib/internal/memory/memcmp (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - br $continue|0 - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end + (func $~lib/memory/memory.init (; 0 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable ) - (func $~lib/memory/memory.compare (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp + (func $~lib/memory/memory.drop (; 1 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable ) - (func $~lib/allocator/buddy/update_max_ptr (; 2 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) + (func $assembly/buddy/update_max_ptr (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 - global.get $~lib/allocator/buddy/max_ptr + global.get $assembly/buddy/max_ptr i32.gt_u if local.get $0 @@ -91,7 +46,7 @@ i32.and i32.const 16 i32.shr_u - local.tee $1 + local.tee $0 current_memory i32.sub grow_memory @@ -101,21 +56,21 @@ i32.const 0 return end - local.get $1 + local.get $0 i32.const 16 i32.shl - global.set $~lib/allocator/buddy/max_ptr + global.set $assembly/buddy/max_ptr end i32.const 1 ) - (func $~lib/allocator/buddy/buckets$get (; 3 ;) (type $ii) (param $0 i32) (result i32) - global.get $~lib/allocator/buddy/BUCKETS_START + (func $assembly/buddy/buckets$get (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + global.get $assembly/buddy/BUCKETS_START local.get $0 i32.const 3 i32.shl i32.add ) - (func $~lib/allocator/buddy/list_init (; 4 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/list_init (; 4 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 local.get $0 i32.store @@ -123,7 +78,7 @@ local.get $0 i32.store offset=4 ) - (func $~lib/allocator/buddy/list_push (; 5 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $assembly/buddy/list_push (; 5 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) local.get $1 local.get $0 @@ -140,7 +95,7 @@ local.get $1 i32.store ) - (func $~lib/allocator/buddy/bucket_for_request (; 6 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/bucket_for_request (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) i32.const 26 @@ -165,12 +120,12 @@ end local.get $1 ) - (func $~lib/allocator/buddy/node_for_ptr (; 7 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $assembly/buddy/node_for_ptr (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) i32.const 1 local.get $1 i32.shl local.get $0 - global.get $~lib/allocator/buddy/base_ptr + global.get $assembly/buddy/base_ptr i32.sub i32.const 30 local.get $1 @@ -180,13 +135,13 @@ i32.const 1 i32.sub ) - (func $~lib/allocator/buddy/node_is_split$get (; 8 ;) (type $ii) (param $0 i32) (result i32) - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START + (func $assembly/buddy/node_is_split$get (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + global.get $assembly/buddy/NODE_IS_SPLIT_START local.get $0 i32.add i32.load8_u ) - (func $~lib/allocator/buddy/parent_is_split (; 9 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/parent_is_split (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 1 i32.sub @@ -195,7 +150,7 @@ local.tee $0 i32.const 8 i32.div_u - call $~lib/allocator/buddy/node_is_split$get + call $assembly/buddy/node_is_split$get local.get $0 i32.const 7 i32.and @@ -205,7 +160,7 @@ i32.const 1 i32.eq ) - (func $~lib/allocator/buddy/list_remove (; 10 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/list_remove (; 10 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load @@ -218,8 +173,8 @@ local.get $1 i32.store ) - (func $~lib/allocator/buddy/ptr_for_node (; 11 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) - global.get $~lib/allocator/buddy/base_ptr + (func $assembly/buddy/ptr_for_node (; 11 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + global.get $assembly/buddy/base_ptr local.get $0 i32.const 1 local.get $1 @@ -233,7 +188,7 @@ i32.shl i32.add ) - (func $~lib/allocator/buddy/flip_parent_is_split (; 12 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/flip_parent_is_split (; 12 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) local.get $0 @@ -247,7 +202,7 @@ local.tee $1 local.set $2 local.get $1 - call $~lib/allocator/buddy/node_is_split$get + call $assembly/buddy/node_is_split$get i32.const 1 local.get $0 i32.const 7 @@ -255,102 +210,103 @@ i32.shl i32.xor local.set $0 - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/NODE_IS_SPLIT_START local.get $2 i32.add local.get $0 i32.store8 ) - (func $~lib/allocator/buddy/lower_bucket_limit (; 13 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/lower_bucket_limit (; 13 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) loop $continue|0 local.get $0 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.lt_u if - global.get $~lib/allocator/buddy/base_ptr - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/node_for_ptr - local.tee $1 - call $~lib/allocator/buddy/parent_is_split + global.get $assembly/buddy/base_ptr + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/node_for_ptr + local.tee $2 + call $assembly/buddy/parent_is_split i32.eqz if - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_remove + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_remove block (result i32) - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.const 1 i32.sub - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/bucket_limit + local.tee $1 + global.set $assembly/buddy/bucket_limit + local.get $1 end - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/buckets$get - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_push + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/buckets$get + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_push br $continue|0 end - local.get $1 + local.get $2 i32.const 1 i32.add - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/ptr_for_node - local.tee $2 + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/ptr_for_node + local.tee $1 i32.const 8 i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if i32.const 0 return end - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/buckets$get - local.get $2 - call $~lib/allocator/buddy/list_push + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/buckets$get + local.get $1 + call $assembly/buddy/list_push block (result i32) - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.const 1 i32.sub - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/bucket_limit + local.tee $1 + global.set $assembly/buddy/bucket_limit + local.get $1 end - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init - local.get $1 + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init + local.get $2 i32.const 1 i32.sub i32.const 2 i32.div_u - local.tee $1 + local.tee $2 if - local.get $1 - call $~lib/allocator/buddy/flip_parent_is_split + local.get $2 + call $assembly/buddy/flip_parent_is_split end br $continue|0 end end i32.const 1 ) - (func $~lib/allocator/buddy/list_pop (; 14 ;) (type $ii) (param $0 i32) (result i32) - (local $1 i32) + (func $assembly/buddy/list_pop (; 14 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + local.get $0 local.get $0 i32.load - local.tee $1 - local.get $0 + local.tee $0 i32.eq if i32.const 0 return end - local.get $1 - call $~lib/allocator/buddy/list_remove - local.get $1 + local.get $0 + call $assembly/buddy/list_remove + local.get $0 ) - (func $~lib/allocator/buddy/__memory_allocate (; 15 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/__memory_allocate (; 15 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -361,42 +317,42 @@ if unreachable end - global.get $~lib/allocator/buddy/base_ptr + global.get $assembly/buddy/base_ptr i32.eqz if - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_END + global.get $assembly/buddy/NODE_IS_SPLIT_END i32.const 7 i32.add i32.const -8 i32.and - global.set $~lib/allocator/buddy/base_ptr + global.set $assembly/buddy/base_ptr current_memory i32.const 16 i32.shl - global.set $~lib/allocator/buddy/max_ptr + global.set $assembly/buddy/max_ptr i32.const 26 - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/base_ptr + global.set $assembly/buddy/bucket_limit + global.get $assembly/buddy/base_ptr i32.const 8 i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if i32.const 0 return end i32.const 26 - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init i32.const 26 - call $~lib/allocator/buddy/buckets$get - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_push + call $assembly/buddy/buckets$get + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_push end local.get $0 i32.const 8 i32.add - call $~lib/allocator/buddy/bucket_for_request + call $assembly/buddy/bucket_for_request local.tee $1 local.set $4 loop $continue|0 @@ -405,20 +361,20 @@ i32.ne if local.get $1 - call $~lib/allocator/buddy/lower_bucket_limit + call $assembly/buddy/lower_bucket_limit i32.eqz if i32.const 0 return end local.get $1 - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_pop + call $assembly/buddy/buckets$get + call $assembly/buddy/list_pop local.tee $2 i32.eqz if local.get $1 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.ne local.tee $2 if (result i32) @@ -437,15 +393,15 @@ local.get $1 i32.const 1 i32.sub - call $~lib/allocator/buddy/lower_bucket_limit + call $assembly/buddy/lower_bucket_limit i32.eqz if i32.const 0 return end local.get $1 - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_pop + call $assembly/buddy/buckets$get + call $assembly/buddy/list_pop local.set $2 end i32.const 1 @@ -468,23 +424,23 @@ end local.get $2 i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if local.get $1 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $2 - call $~lib/allocator/buddy/list_push + call $assembly/buddy/list_push i32.const 0 return end local.get $2 local.get $1 - call $~lib/allocator/buddy/node_for_ptr + call $assembly/buddy/node_for_ptr local.tee $3 if local.get $3 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split end loop $continue|1 local.get $1 @@ -497,18 +453,18 @@ i32.const 1 i32.add local.tee $3 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split local.get $1 i32.const 1 i32.add local.tee $1 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $3 i32.const 1 i32.add local.get $1 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_push + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_push br $continue|1 end end @@ -523,11 +479,11 @@ end i32.const 0 ) - (func $~lib/memory/memory.allocate (; 16 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/memory/memory.allocate (; 16 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 - call $~lib/allocator/buddy/__memory_allocate + call $assembly/buddy/__memory_allocate ) - (func $~lib/allocator/buddy/__memory_free (; 17 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/__memory_free (; 17 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) local.get $0 @@ -542,26 +498,26 @@ i32.load i32.const 8 i32.add - call $~lib/allocator/buddy/bucket_for_request + call $assembly/buddy/bucket_for_request local.set $1 local.get $0 local.get $1 - call $~lib/allocator/buddy/node_for_ptr + call $assembly/buddy/node_for_ptr local.set $0 loop $continue|0 local.get $0 if block $break|0 local.get $0 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split local.get $0 - call $~lib/allocator/buddy/parent_is_split + call $assembly/buddy/parent_is_split local.tee $2 if (result i32) local.get $2 else local.get $1 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.eq end br_if $break|0 @@ -573,8 +529,8 @@ i32.const 1 i32.add local.get $1 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_remove + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_remove local.get $0 i32.const 1 i32.sub @@ -590,34 +546,1356 @@ end end local.get $1 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $0 local.get $1 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_push + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_push ) - (func $~lib/memory/memory.free (; 18 ;) (type $i_) (param $0 i32) + (func $~lib/memory/memory.free (; 18 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 - call $~lib/allocator/buddy/__memory_free + call $assembly/buddy/__memory_free ) - (func $~lib/memory/memory.reset (; 19 ;) (type $_) + (func $~lib/memory/memory.reset (; 19 ;) (type $FUNCSIG$v) unreachable ) - (func $start (; 20 ;) (type $_) + (func $~lib/util/memory/memcpy (; 20 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + loop $continue|0 + local.get $1 + i32.const 3 + i32.and + local.get $2 + local.get $2 + select + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|0 + end + end + local.get $0 + i32.const 3 + i32.and + i32.eqz + if + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|1 + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $1 + i32.const 8 + i32.add + local.set $1 + local.get $0 + i32.const 8 + i32.add + local.set $0 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $1 + i32.const 4 + i32.add + local.set $1 + local.get $0 + i32.const 4 + i32.add + local.set $0 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $1 + i32.const 2 + i32.add + local.set $1 + local.get $0 + i32.const 2 + i32.add + local.set $0 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + i32.const 1 + i32.sub + br_table $case0|2 $case1|2 $case2|2 $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 1 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 5 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 9 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 13 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|3 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 2 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 6 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 10 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 14 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|4 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 3 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 7 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 11 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 15 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|5 + end + end + end + end + local.get $2 + i32.const 16 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 i32.const 8 - global.set $~lib/allocator/buddy/BUCKETS_START - global.get $~lib/allocator/buddy/BUCKETS_START + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + ) + (func $~lib/memory/memory.copy (; 21 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + br_if $~lib/util/memory/memmove|inlined.0 + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $3 + if (result i32) + local.get $3 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + br $continue|0 + end + end + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + br $continue|1 + end + end + end + loop $continue|2 + local.get $2 + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|2 + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|3 + end + end + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $2 + i32.const 8 + i32.sub + local.tee $2 + local.get $0 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + br $continue|4 + end + end + end + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 22 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + local.get $2 + local.get $3 + i32.mul + local.set $3 + loop $continue|0 + local.get $4 + local.get $3 + i32.lt_u + if + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $2 + local.get $4 + i32.add + local.set $4 + br $continue|0 + end + end + ) + (func $~lib/memory/memory.compare (; 23 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + local.get $0 + local.get $1 + i32.eq + if (result i32) + i32.const 0 + else + loop $continue|0 + local.get $2 + i32.const 0 + i32.ne + local.tee $3 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.eq + else + local.get $3 + end + if + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + i32.const 1 + i32.add + local.set $0 + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $continue|0 + end + end + local.get $2 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $start (; 24 ;) (type $FUNCSIG$v) + i32.const 8 + global.set $assembly/buddy/BUCKETS_START + global.get $assembly/buddy/BUCKETS_START i32.const 216 i32.add - global.set $~lib/allocator/buddy/BUCKETS_END - global.get $~lib/allocator/buddy/BUCKETS_END - global.set $~lib/allocator/buddy/NODE_IS_SPLIT_START - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START + global.set $assembly/buddy/BUCKETS_END + global.get $assembly/buddy/BUCKETS_END + global.set $assembly/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/NODE_IS_SPLIT_START i32.const 8388608 i32.add - global.set $~lib/allocator/buddy/NODE_IS_SPLIT_END + global.set $assembly/buddy/NODE_IS_SPLIT_END ) - (func $null (; 21 ;) (type $_) + (func $null (; 25 ;) (type $FUNCSIG$v) nop ) ) diff --git a/tests/allocators/buddy/untouched.wat b/tests/allocators/buddy/untouched.wat index b67987cb..5f8c771f 100644 --- a/tests/allocators/buddy/untouched.wat +++ b/tests/allocators/buddy/untouched.wat @@ -1,125 +1,76 @@ (module - (type $_ (func)) - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $iiii_ (func (param i32 i32 i32 i32))) - (type $i_ (func (param i32))) - (type $ii_ (func (param i32 i32))) - (type $iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result 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$iiii (func (param i32 i32 i32) (result i32))) (import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32))) (memory $0 1) - (data (i32.const 8) "\17\00\00\00~\00l\00i\00b\00/\00a\00l\00l\00o\00c\00a\00t\00o\00r\00/\00b\00u\00d\00d\00y\00.\00t\00s\00") + (data (i32.const 8) "\01\00\00\00\"\00\00\00a\00s\00s\00e\00m\00b\00l\00y\00/\00b\00u\00d\00d\00y\00.\00t\00s\00") (table $0 1 funcref) (elem (i32.const 0) $null) - (global $~lib/allocator/buddy/HEADER_SIZE i32 (i32.const 8)) - (global $~lib/allocator/buddy/MIN_ALLOC_LOG2 i32 (i32.const 4)) - (global $~lib/allocator/buddy/MIN_ALLOC i32 (i32.const 16)) - (global $~lib/allocator/buddy/MAX_ALLOC_LOG2 i32 (i32.const 30)) - (global $~lib/allocator/buddy/MAX_ALLOC i32 (i32.const 1073741824)) - (global $~lib/allocator/buddy/BUCKET_COUNT i32 (i32.const 27)) - (global $~lib/allocator/buddy/List.SIZE i32 (i32.const 8)) - (global $~lib/allocator/buddy/BUCKETS_START (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/BUCKETS_END (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/bucket_limit (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/SPLIT_COUNT i32 (i32.const 8388608)) - (global $~lib/allocator/buddy/NODE_IS_SPLIT_START (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/NODE_IS_SPLIT_END (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/base_ptr (mut i32) (i32.const 0)) - (global $~lib/allocator/buddy/max_ptr (mut i32) (i32.const 0)) - (global $~lib/memory/HEAP_BASE i32 (i32.const 60)) + (global $assembly/buddy/HEADER_SIZE i32 (i32.const 8)) + (global $assembly/buddy/MIN_ALLOC_LOG2 i32 (i32.const 4)) + (global $assembly/buddy/MIN_ALLOC i32 (i32.const 16)) + (global $assembly/buddy/MAX_ALLOC_LOG2 i32 (i32.const 30)) + (global $assembly/buddy/MAX_ALLOC i32 (i32.const 1073741824)) + (global $assembly/buddy/BUCKET_COUNT i32 (i32.const 27)) + (global $assembly/buddy/List.SIZE i32 (i32.const 8)) + (global $assembly/buddy/BUCKETS_START (mut i32) (i32.const 0)) + (global $assembly/buddy/BUCKETS_END (mut i32) (i32.const 0)) + (global $assembly/buddy/bucket_limit (mut i32) (i32.const 0)) + (global $assembly/buddy/SPLIT_COUNT i32 (i32.const 8388608)) + (global $assembly/buddy/NODE_IS_SPLIT_START (mut i32) (i32.const 0)) + (global $assembly/buddy/NODE_IS_SPLIT_END (mut i32) (i32.const 0)) + (global $assembly/buddy/base_ptr (mut i32) (i32.const 0)) + (global $assembly/buddy/max_ptr (mut i32) (i32.const 0)) + (global $~lib/memory/HEAP_BASE i32 (i32.const 52)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) (start $start) - (func $start:~lib/allocator/buddy (; 1 ;) (type $_) + (func $start:assembly/buddy (; 1 ;) (type $FUNCSIG$v) global.get $~lib/memory/HEAP_BASE - global.set $~lib/allocator/buddy/BUCKETS_START - global.get $~lib/allocator/buddy/BUCKETS_START - global.get $~lib/allocator/buddy/BUCKET_COUNT - global.get $~lib/allocator/buddy/List.SIZE + global.set $assembly/buddy/BUCKETS_START + global.get $assembly/buddy/BUCKETS_START + global.get $assembly/buddy/BUCKET_COUNT + global.get $assembly/buddy/List.SIZE i32.mul i32.add - global.set $~lib/allocator/buddy/BUCKETS_END - global.get $~lib/allocator/buddy/BUCKETS_END - global.set $~lib/allocator/buddy/NODE_IS_SPLIT_START - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START - global.get $~lib/allocator/buddy/SPLIT_COUNT + global.set $assembly/buddy/BUCKETS_END + global.get $assembly/buddy/BUCKETS_END + global.set $assembly/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/SPLIT_COUNT i32.const 1 i32.mul i32.add - global.set $~lib/allocator/buddy/NODE_IS_SPLIT_END + global.set $assembly/buddy/NODE_IS_SPLIT_END ) - (func $start:assembly/index (; 2 ;) (type $_) - call $start:~lib/allocator/buddy + (func $start:assembly/index (; 2 ;) (type $FUNCSIG$v) + call $start:assembly/buddy ) - (func $~lib/internal/memory/memcmp (; 3 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - block $break|0 - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - block - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - end - br $continue|0 - end - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end + (func $~lib/memory/memory.init (; 3 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable ) - (func $~lib/memory/memory.compare (; 4 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp + (func $~lib/memory/memory.drop (; 4 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable ) - (func $~lib/allocator/buddy/update_max_ptr (; 5 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/update_max_ptr (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) local.get $0 - global.get $~lib/allocator/buddy/max_ptr + global.get $assembly/buddy/max_ptr i32.gt_u if current_memory @@ -140,8 +91,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 181 + i32.const 16 + i32.const 176 i32.const 4 call $~lib/env/abort unreachable @@ -159,30 +110,30 @@ local.get $2 i32.const 16 i32.shl - global.set $~lib/allocator/buddy/max_ptr + global.set $assembly/buddy/max_ptr end i32.const 1 ) - (func $~lib/allocator/buddy/buckets$get (; 6 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/buckets$get (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 - global.get $~lib/allocator/buddy/BUCKET_COUNT + global.get $assembly/buddy/BUCKET_COUNT i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 101 + i32.const 16 + i32.const 96 i32.const 2 call $~lib/env/abort unreachable end - global.get $~lib/allocator/buddy/BUCKETS_START + global.get $assembly/buddy/BUCKETS_START local.get $0 - global.get $~lib/allocator/buddy/List.SIZE + global.get $assembly/buddy/List.SIZE i32.mul i32.add ) - (func $~lib/allocator/buddy/list_init (; 7 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/list_init (; 7 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 local.get $0 i32.store @@ -190,7 +141,7 @@ local.get $0 i32.store offset=4 ) - (func $~lib/allocator/buddy/list_push (; 8 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $assembly/buddy/list_push (; 8 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) local.get $0 i32.load @@ -208,14 +159,14 @@ local.get $1 i32.store ) - (func $~lib/allocator/buddy/bucket_for_request (; 9 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/bucket_for_request (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) - global.get $~lib/allocator/buddy/BUCKET_COUNT + global.get $assembly/buddy/BUCKET_COUNT i32.const 1 i32.sub local.set $1 - global.get $~lib/allocator/buddy/MIN_ALLOC + global.get $assembly/buddy/MIN_ALLOC local.set $2 block $break|0 loop $continue|0 @@ -239,11 +190,11 @@ end local.get $1 ) - (func $~lib/allocator/buddy/node_for_ptr (; 10 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $assembly/buddy/node_for_ptr (; 10 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) local.get $0 - global.get $~lib/allocator/buddy/base_ptr + global.get $assembly/buddy/base_ptr i32.sub - global.get $~lib/allocator/buddy/MAX_ALLOC_LOG2 + global.get $assembly/buddy/MAX_ALLOC_LOG2 local.get $1 i32.sub i32.shr_u @@ -254,25 +205,25 @@ i32.const 1 i32.sub ) - (func $~lib/allocator/buddy/node_is_split$get (; 11 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/node_is_split$get (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 - global.get $~lib/allocator/buddy/SPLIT_COUNT + global.get $assembly/buddy/SPLIT_COUNT i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 147 + i32.const 16 + i32.const 142 i32.const 2 call $~lib/env/abort unreachable end - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/NODE_IS_SPLIT_START local.get $0 i32.add i32.load8_u ) - (func $~lib/allocator/buddy/parent_is_split (; 12 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/parent_is_split (; 12 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 1 i32.sub @@ -282,7 +233,7 @@ local.get $0 i32.const 8 i32.div_u - call $~lib/allocator/buddy/node_is_split$get + call $assembly/buddy/node_is_split$get local.get $0 i32.const 8 i32.rem_u @@ -292,7 +243,7 @@ i32.const 1 i32.eq ) - (func $~lib/allocator/buddy/list_remove (; 13 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/list_remove (; 13 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) local.get $0 @@ -308,8 +259,8 @@ local.get $1 i32.store ) - (func $~lib/allocator/buddy/ptr_for_node (; 14 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) - global.get $~lib/allocator/buddy/base_ptr + (func $assembly/buddy/ptr_for_node (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + global.get $assembly/buddy/base_ptr local.get $0 i32.const 1 local.get $1 @@ -317,32 +268,32 @@ i32.sub i32.const 1 i32.add - global.get $~lib/allocator/buddy/MAX_ALLOC_LOG2 + global.get $assembly/buddy/MAX_ALLOC_LOG2 local.get $1 i32.sub i32.shl i32.add ) - (func $~lib/allocator/buddy/node_is_split$set (; 15 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $assembly/buddy/node_is_split$set (; 15 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) local.get $0 - global.get $~lib/allocator/buddy/SPLIT_COUNT + global.get $assembly/buddy/SPLIT_COUNT i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 152 + i32.const 16 + i32.const 147 i32.const 2 call $~lib/env/abort unreachable end - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_START + global.get $assembly/buddy/NODE_IS_SPLIT_START local.get $0 i32.add local.get $1 i32.store8 ) - (func $~lib/allocator/buddy/flip_parent_is_split (; 16 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/flip_parent_is_split (; 16 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.const 1 @@ -356,78 +307,81 @@ local.set $1 local.get $1 local.get $1 - call $~lib/allocator/buddy/node_is_split$get + call $assembly/buddy/node_is_split$get i32.const 1 local.get $0 i32.const 8 i32.rem_u i32.shl i32.xor - call $~lib/allocator/buddy/node_is_split$set + call $assembly/buddy/node_is_split$set ) - (func $~lib/allocator/buddy/lower_bucket_limit (; 17 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/lower_bucket_limit (; 17 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) + (local $3 i32) block $break|0 loop $continue|0 local.get $0 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.lt_u if block - global.get $~lib/allocator/buddy/base_ptr - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/node_for_ptr + global.get $assembly/buddy/base_ptr + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/node_for_ptr local.set $1 local.get $1 - call $~lib/allocator/buddy/parent_is_split + call $assembly/buddy/parent_is_split i32.eqz if - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_remove + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_remove block (result i32) - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.const 1 i32.sub - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/bucket_limit + local.tee $3 + global.set $assembly/buddy/bucket_limit + local.get $3 end - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/buckets$get - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_push + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/buckets$get + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_push br $continue|0 end local.get $1 i32.const 1 i32.add - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/ptr_for_node + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/ptr_for_node local.set $2 local.get $2 - global.get $~lib/allocator/buddy/List.SIZE + global.get $assembly/buddy/List.SIZE i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if i32.const 0 return end - global.get $~lib/allocator/buddy/bucket_limit - call $~lib/allocator/buddy/buckets$get + global.get $assembly/buddy/bucket_limit + call $assembly/buddy/buckets$get local.get $2 - call $~lib/allocator/buddy/list_push + call $assembly/buddy/list_push block (result i32) - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.const 1 i32.sub - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/bucket_limit + local.tee $3 + global.set $assembly/buddy/bucket_limit + local.get $3 end - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init local.get $1 i32.const 1 i32.sub @@ -439,7 +393,7 @@ i32.ne if local.get $1 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split end end br $continue|0 @@ -448,7 +402,7 @@ end i32.const 1 ) - (func $~lib/allocator/buddy/list_pop (; 18 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/list_pop (; 18 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) local.get $0 i32.load @@ -461,10 +415,10 @@ return end local.get $1 - call $~lib/allocator/buddy/list_remove + call $assembly/buddy/list_remove local.get $1 ) - (func $~lib/allocator/buddy/__memory_allocate (; 19 ;) (type $ii) (param $0 i32) (result i32) + (func $assembly/buddy/__memory_allocate (; 19 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -473,58 +427,58 @@ (local $6 i32) (local $7 i32) local.get $0 - global.get $~lib/allocator/buddy/MAX_ALLOC - global.get $~lib/allocator/buddy/HEADER_SIZE + global.get $assembly/buddy/MAX_ALLOC + global.get $assembly/buddy/HEADER_SIZE i32.sub i32.gt_u if unreachable end - global.get $~lib/allocator/buddy/base_ptr + global.get $assembly/buddy/base_ptr i32.const 0 i32.eq if - global.get $~lib/allocator/buddy/NODE_IS_SPLIT_END + global.get $assembly/buddy/NODE_IS_SPLIT_END i32.const 7 i32.add i32.const 7 i32.const -1 i32.xor i32.and - global.set $~lib/allocator/buddy/base_ptr + global.set $assembly/buddy/base_ptr current_memory i32.const 16 i32.shl - global.set $~lib/allocator/buddy/max_ptr - global.get $~lib/allocator/buddy/BUCKET_COUNT + global.set $assembly/buddy/max_ptr + global.get $assembly/buddy/BUCKET_COUNT i32.const 1 i32.sub - global.set $~lib/allocator/buddy/bucket_limit - global.get $~lib/allocator/buddy/base_ptr - global.get $~lib/allocator/buddy/List.SIZE + global.set $assembly/buddy/bucket_limit + global.get $assembly/buddy/base_ptr + global.get $assembly/buddy/List.SIZE i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if i32.const 0 return end - global.get $~lib/allocator/buddy/BUCKET_COUNT + global.get $assembly/buddy/BUCKET_COUNT i32.const 1 i32.sub - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_init - global.get $~lib/allocator/buddy/BUCKET_COUNT + call $assembly/buddy/buckets$get + call $assembly/buddy/list_init + global.get $assembly/buddy/BUCKET_COUNT i32.const 1 i32.sub - call $~lib/allocator/buddy/buckets$get - global.get $~lib/allocator/buddy/base_ptr - call $~lib/allocator/buddy/list_push + call $assembly/buddy/buckets$get + global.get $assembly/buddy/base_ptr + call $assembly/buddy/list_push end local.get $0 - global.get $~lib/allocator/buddy/HEADER_SIZE + global.get $assembly/buddy/HEADER_SIZE i32.add - call $~lib/allocator/buddy/bucket_for_request + call $assembly/buddy/bucket_for_request local.set $2 local.get $2 local.set $1 @@ -537,21 +491,21 @@ i32.ne if local.get $2 - call $~lib/allocator/buddy/lower_bucket_limit + call $assembly/buddy/lower_bucket_limit i32.eqz if i32.const 0 return end local.get $2 - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_pop + call $assembly/buddy/buckets$get + call $assembly/buddy/list_pop local.set $6 local.get $6 i32.eqz if local.get $2 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.ne local.tee $7 if (result i32) @@ -571,19 +525,19 @@ local.get $2 i32.const 1 i32.sub - call $~lib/allocator/buddy/lower_bucket_limit + call $assembly/buddy/lower_bucket_limit i32.eqz if i32.const 0 return end local.get $2 - call $~lib/allocator/buddy/buckets$get - call $~lib/allocator/buddy/list_pop + call $assembly/buddy/buckets$get + call $assembly/buddy/list_pop local.set $6 end i32.const 1 - global.get $~lib/allocator/buddy/MAX_ALLOC_LOG2 + global.get $assembly/buddy/MAX_ALLOC_LOG2 local.get $2 i32.sub i32.shl @@ -595,7 +549,7 @@ local.get $3 i32.const 2 i32.div_u - global.get $~lib/allocator/buddy/List.SIZE + global.get $assembly/buddy/List.SIZE i32.add else local.get $3 @@ -604,26 +558,26 @@ local.get $6 local.get $4 i32.add - call $~lib/allocator/buddy/update_max_ptr + call $assembly/buddy/update_max_ptr i32.eqz if local.get $2 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $6 - call $~lib/allocator/buddy/list_push + call $assembly/buddy/list_push i32.const 0 return end local.get $6 local.get $2 - call $~lib/allocator/buddy/node_for_ptr + call $assembly/buddy/node_for_ptr local.set $5 local.get $5 i32.const 0 i32.ne if local.get $5 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split end block $break|1 loop $continue|1 @@ -643,15 +597,15 @@ i32.add local.set $2 local.get $5 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split local.get $2 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $5 i32.const 1 i32.add local.get $2 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_push + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_push end br $continue|1 end @@ -661,7 +615,7 @@ local.get $0 i32.store local.get $6 - global.get $~lib/allocator/buddy/HEADER_SIZE + global.get $assembly/buddy/HEADER_SIZE i32.add return end @@ -669,12 +623,12 @@ end i32.const 0 ) - (func $~lib/memory/memory.allocate (; 20 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/memory/memory.allocate (; 20 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 - call $~lib/allocator/buddy/__memory_allocate + call $assembly/buddy/__memory_allocate return ) - (func $~lib/allocator/buddy/__memory_free (; 21 ;) (type $i_) (param $0 i32) + (func $assembly/buddy/__memory_free (; 21 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -684,18 +638,18 @@ return end local.get $0 - global.get $~lib/allocator/buddy/HEADER_SIZE + global.get $assembly/buddy/HEADER_SIZE i32.sub local.set $0 local.get $0 i32.load - global.get $~lib/allocator/buddy/HEADER_SIZE + global.get $assembly/buddy/HEADER_SIZE i32.add - call $~lib/allocator/buddy/bucket_for_request + call $assembly/buddy/bucket_for_request local.set $1 local.get $0 local.get $1 - call $~lib/allocator/buddy/node_for_ptr + call $assembly/buddy/node_for_ptr local.set $2 block $break|0 loop $continue|0 @@ -705,15 +659,15 @@ if block local.get $2 - call $~lib/allocator/buddy/flip_parent_is_split + call $assembly/buddy/flip_parent_is_split local.get $2 - call $~lib/allocator/buddy/parent_is_split + call $assembly/buddy/parent_is_split local.tee $3 if (result i32) local.get $3 else local.get $1 - global.get $~lib/allocator/buddy/bucket_limit + global.get $assembly/buddy/bucket_limit i32.eq end if @@ -727,8 +681,8 @@ i32.const 1 i32.add local.get $1 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_remove + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_remove local.get $2 i32.const 1 i32.sub @@ -745,23 +699,1551 @@ end end local.get $1 - call $~lib/allocator/buddy/buckets$get + call $assembly/buddy/buckets$get local.get $2 local.get $1 - call $~lib/allocator/buddy/ptr_for_node - call $~lib/allocator/buddy/list_push + call $assembly/buddy/ptr_for_node + call $assembly/buddy/list_push ) - (func $~lib/memory/memory.free (; 22 ;) (type $i_) (param $0 i32) + (func $~lib/memory/memory.free (; 22 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 - call $~lib/allocator/buddy/__memory_free - return + call $assembly/buddy/__memory_free ) - (func $~lib/memory/memory.reset (; 23 ;) (type $_) + (func $~lib/memory/memory.reset (; 23 ;) (type $FUNCSIG$v) unreachable ) - (func $start (; 24 ;) (type $_) + (func $~lib/util/memory/memcpy (; 24 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $break|0 + loop $continue|0 + local.get $2 + if (result i32) + local.get $1 + i32.const 3 + i32.and + else + local.get $2 + end + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|0 + end + end + end + local.get $0 + i32.const 3 + i32.and + i32.const 0 + i32.eq + if + block $break|1 + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + block + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|1 + end + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.set $0 + local.get $1 + i32.const 4 + i32.add + local.set $1 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $0 + i32.const 2 + i32.add + local.set $0 + local.get $1 + i32.const 2 + i32.add + local.set $1 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + local.set $5 + local.get $5 + i32.const 1 + i32.eq + br_if $case0|2 + local.get $5 + i32.const 2 + i32.eq + br_if $case1|2 + local.get $5 + i32.const 3 + i32.eq + br_if $case2|2 + br $break|2 + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + block $break|3 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + block + local.get $1 + i32.const 1 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 5 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 9 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 13 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|3 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + block $break|4 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + block + local.get $1 + i32.const 2 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 6 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 10 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 14 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|4 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block $break|5 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + block + local.get $1 + i32.const 3 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 7 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 11 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 15 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|5 + end + end + end + br $break|2 + unreachable + end + unreachable + end + end + local.get $2 + i32.const 16 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 8 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + ) + (func $~lib/memory/memory.copy (; 25 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $5 + if (result i32) + local.get $5 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|0 + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + br $continue|0 + end + end + end + block $break|1 + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + br $continue|1 + end + end + end + end + block $break|2 + loop $continue|2 + local.get $2 + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|2 + end + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|3 + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + end + br $continue|3 + end + end + end + block $break|4 + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + local.get $2 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + end + br $continue|4 + end + end + end + end + block $break|5 + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 26 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + i32.const 0 + local.set $4 + local.get $2 + local.get $3 + i32.mul + local.set $5 + block $break|0 + loop $continue|0 + local.get $4 + local.get $5 + i32.lt_u + if + block + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $4 + local.get $2 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + ) + (func $~lib/memory/memory.compare (; 27 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + block $~lib/util/memory/memcmp|inlined.0 (result i32) + local.get $0 + local.set $5 + local.get $1 + local.set $4 + local.get $2 + local.set $3 + local.get $5 + local.get $4 + i32.eq + if + i32.const 0 + br $~lib/util/memory/memcmp|inlined.0 + end + block $break|0 + loop $continue|0 + local.get $3 + i32.const 0 + i32.ne + local.tee $6 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.eq + else + local.get $6 + end + if + block + local.get $3 + i32.const 1 + i32.sub + local.set $3 + local.get $5 + i32.const 1 + i32.add + local.set $5 + local.get $4 + i32.const 1 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + local.get $3 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $start (; 28 ;) (type $FUNCSIG$v) call $start:assembly/index ) - (func $null (; 25 ;) (type $_) + (func $null (; 29 ;) (type $FUNCSIG$v) ) ) diff --git a/tests/allocators/tlsf/optimized.wat b/tests/allocators/tlsf/optimized.wat index a0da81d0..edc38303 100644 --- a/tests/allocators/tlsf/optimized.wat +++ b/tests/allocators/tlsf/optimized.wat @@ -1,85 +1,38 @@ (module - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $ii_ (func (param i32 i32))) - (type $iii_ (func (param i32 i32 i32))) - (type $iiii_ (func (param i32 i32 i32 i32))) - (type $iii (func (param i32 i32) (result i32))) - (type $i_ (func (param i32))) - (type $_ (func)) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$vii (func (param i32 i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$v (func)) (memory $0 0) (table $0 1 funcref) (elem (i32.const 0) $null) (global $~lib/allocator/tlsf/ROOT (mut i32) (i32.const 0)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) - (func $~lib/internal/memory/memcmp (; 0 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - br $continue|0 - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) + (func $~lib/memory/memory.init (; 0 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable ) - (func $~lib/memory/memory.compare (; 1 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp + (func $~lib/memory/memory.drop (; 1 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable ) (func $~lib/allocator/tlsf/Root#set:tailRef (; 2 ;) (type $FUNCSIG$vi) (param $0 i32) i32.const 2912 local.get $0 i32.store ) - (func $~lib/allocator/tlsf/Root#setSLMap (; 3 ;) (type $iii_) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/allocator/tlsf/Root#setSLMap (; 3 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) local.get $0 local.get $1 i32.const 2 @@ -88,7 +41,7 @@ local.get $2 i32.store offset=4 ) - (func $~lib/allocator/tlsf/Root#setHead (; 4 ;) (type $iiii_) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $~lib/allocator/tlsf/Root#setHead (; 4 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) local.get $0 local.get $1 i32.const 5 @@ -101,7 +54,7 @@ local.get $3 i32.store offset=96 ) - (func $~lib/allocator/tlsf/Block#get:right (; 5 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/Block#get:right (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 8 i32.add @@ -111,13 +64,13 @@ i32.and i32.add ) - (func $~lib/allocator/tlsf/fls (; 6 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/fls (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) i32.const 31 local.get $0 i32.clz i32.sub ) - (func $~lib/allocator/tlsf/Root#getHead (; 7 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#getHead (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) local.get $0 local.get $1 i32.const 5 @@ -129,7 +82,7 @@ i32.add i32.load offset=96 ) - (func $~lib/allocator/tlsf/Root#getSLMap (; 8 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/allocator/tlsf/Root#getSLMap (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) local.get $0 local.get $1 i32.const 2 @@ -137,7 +90,7 @@ i32.add i32.load offset=4 ) - (func $~lib/allocator/tlsf/Root#remove (; 9 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $~lib/allocator/tlsf/Root#remove (; 9 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -233,7 +186,7 @@ end end ) - (func $~lib/allocator/tlsf/Root#insert (; 10 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $~lib/allocator/tlsf/Root#insert (; 10 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -373,7 +326,7 @@ i32.or call $~lib/allocator/tlsf/Root#setSLMap ) - (func $~lib/allocator/tlsf/Root#addMemory (; 11 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#addMemory (; 11 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) local.get $2 block (result i32) @@ -403,7 +356,6 @@ i32.const 32 i32.lt_u if - i32.const 0 return end local.get $1 @@ -436,9 +388,8 @@ local.get $0 local.get $1 call $~lib/allocator/tlsf/Root#insert - i32.const 1 ) - (func $~lib/allocator/tlsf/Root#search (; 12 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/allocator/tlsf/Root#search (; 12 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) local.get $1 i32.const 256 @@ -519,7 +470,7 @@ end end ) - (func $~lib/allocator/tlsf/Root#use (; 13 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#use (; 13 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) local.get $1 @@ -578,91 +529,93 @@ i32.const 8 i32.add ) - (func $~lib/allocator/tlsf/__memory_allocate (; 14 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/memory/memory.allocate (; 14 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) + local.get $0 + local.set $3 global.get $~lib/allocator/tlsf/ROOT - local.tee $1 + local.tee $0 i32.eqz if i32.const 8 - local.tee $4 + local.tee $5 i32.const 68451 i32.add i32.const -65536 i32.and i32.const 16 i32.shr_u - local.tee $5 + local.tee $1 current_memory - local.tee $2 + local.tee $4 i32.gt_s - local.tee $3 + local.tee $2 if (result i32) - local.get $5 - local.get $2 + local.get $1 + local.get $4 i32.sub grow_memory i32.const 0 i32.lt_s else - local.get $3 + local.get $2 end if unreachable end - local.get $4 - local.tee $1 + local.get $5 + local.tee $0 global.set $~lib/allocator/tlsf/ROOT i32.const 0 call $~lib/allocator/tlsf/Root#set:tailRef - local.get $1 + local.get $0 i32.const 0 i32.store i32.const 0 - local.set $3 + local.set $2 loop $repeat|0 block $break|0 - local.get $3 + local.get $2 i32.const 22 i32.ge_u br_if $break|0 - local.get $1 - local.get $3 + local.get $0 + local.get $2 i32.const 0 call $~lib/allocator/tlsf/Root#setSLMap i32.const 0 - local.set $2 + local.set $1 loop $repeat|1 block $break|1 - local.get $2 + local.get $1 i32.const 32 i32.ge_u br_if $break|1 - local.get $1 - local.get $3 + local.get $0 local.get $2 + local.get $1 i32.const 0 call $~lib/allocator/tlsf/Root#setHead - local.get $2 + local.get $1 i32.const 1 i32.add - local.set $2 + local.set $1 br $repeat|1 end end - local.get $3 + local.get $2 i32.const 1 i32.add - local.set $3 + local.set $2 br $repeat|0 end end - local.get $1 - local.get $4 + local.get $0 + local.get $5 i32.const 2923 i32.add i32.const -8 @@ -671,55 +624,54 @@ i32.const 16 i32.shl call $~lib/allocator/tlsf/Root#addMemory - drop end - local.get $0 + local.get $3 i32.const 1073741824 i32.gt_u if unreachable end - local.get $1 - local.get $1 local.get $0 + local.get $0 + local.get $3 i32.const 7 i32.add i32.const -8 i32.and - local.tee $5 + local.tee $1 i32.const 16 - local.tee $2 - local.get $5 - local.get $2 + local.tee $4 + local.get $1 + local.get $4 i32.gt_u select - local.tee $0 + local.tee $3 call $~lib/allocator/tlsf/Root#search - local.tee $4 + local.tee $1 if (result i32) - local.get $4 + local.get $1 else current_memory - local.tee $5 local.tee $4 - local.get $0 + local.tee $2 + local.get $3 i32.const 65535 i32.add i32.const -65536 i32.and i32.const 16 i32.shr_u - local.tee $2 - local.tee $3 - local.get $4 - local.get $3 + local.tee $5 + local.tee $1 + local.get $2 + local.get $1 i32.gt_s select grow_memory i32.const 0 i32.lt_s if - local.get $2 + local.get $5 grow_memory i32.const 0 i32.lt_s @@ -727,27 +679,22 @@ unreachable end end - local.get $1 - local.get $5 + local.get $0 + local.get $4 i32.const 16 i32.shl current_memory i32.const 16 i32.shl call $~lib/allocator/tlsf/Root#addMemory - drop - local.get $1 local.get $0 + local.get $3 call $~lib/allocator/tlsf/Root#search end - local.get $0 + local.get $3 call $~lib/allocator/tlsf/Root#use ) - (func $~lib/memory/memory.allocate (; 15 ;) (type $ii) (param $0 i32) (result i32) - local.get $0 - call $~lib/allocator/tlsf/__memory_allocate - ) - (func $~lib/allocator/tlsf/__memory_free (; 16 ;) (type $i_) (param $0 i32) + (func $~lib/memory/memory.free (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) local.get $0 @@ -772,14 +719,1332 @@ end end ) - (func $~lib/memory/memory.free (; 17 ;) (type $i_) (param $0 i32) - local.get $0 - call $~lib/allocator/tlsf/__memory_free - ) - (func $~lib/memory/memory.reset (; 18 ;) (type $_) + (func $~lib/memory/memory.reset (; 16 ;) (type $FUNCSIG$v) unreachable ) - (func $null (; 19 ;) (type $_) + (func $~lib/util/memory/memcpy (; 17 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + loop $continue|0 + local.get $1 + i32.const 3 + i32.and + local.get $2 + local.get $2 + select + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|0 + end + end + local.get $0 + i32.const 3 + i32.and + i32.eqz + if + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|1 + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $1 + i32.const 8 + i32.add + local.set $1 + local.get $0 + i32.const 8 + i32.add + local.set $0 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $1 + i32.const 4 + i32.add + local.set $1 + local.get $0 + i32.const 4 + i32.add + local.set $0 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $1 + i32.const 2 + i32.add + local.set $1 + local.get $0 + i32.const 2 + i32.add + local.set $0 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + i32.const 1 + i32.sub + br_table $case0|2 $case1|2 $case2|2 $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 1 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 5 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 9 + i32.add + i32.load + local.tee $3 + i32.const 8 + i32.shl + local.get $4 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 13 + i32.add + i32.load + local.tee $4 + i32.const 8 + i32.shl + local.get $3 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|3 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 2 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 6 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 10 + i32.add + i32.load + local.tee $3 + i32.const 16 + i32.shl + local.get $4 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 14 + i32.add + i32.load + local.tee $4 + i32.const 16 + i32.shl + local.get $3 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|4 + end + end + br $break|2 + end + local.get $1 + i32.load + local.set $4 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + local.get $0 + local.get $1 + i32.const 3 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 7 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 11 + i32.add + i32.load + local.tee $3 + i32.const 24 + i32.shl + local.get $4 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 15 + i32.add + i32.load + local.tee $4 + i32.const 24 + i32.shl + local.get $3 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + br $continue|5 + end + end + end + end + local.get $2 + i32.const 16 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + local.get $0 + local.set $3 + local.get $3 + block (result i32) + local.get $1 + local.set $3 + local.get $3 + i32.load8_u + end + i32.store8 + end + ) + (func $~lib/memory/memory.copy (; 18 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + br_if $~lib/util/memory/memmove|inlined.0 + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $3 + if (result i32) + local.get $3 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + br $continue|0 + end + end + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + br $continue|1 + end + end + end + loop $continue|2 + local.get $2 + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|2 + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|3 + end + end + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $2 + i32.const 8 + i32.sub + local.tee $2 + local.get $0 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + br $continue|4 + end + end + end + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 19 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + local.get $2 + local.get $3 + i32.mul + local.set $3 + loop $continue|0 + local.get $4 + local.get $3 + i32.lt_u + if + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $2 + local.get $4 + i32.add + local.set $4 + br $continue|0 + end + end + ) + (func $~lib/memory/memory.compare (; 20 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + local.get $0 + local.get $1 + i32.eq + if (result i32) + i32.const 0 + else + loop $continue|0 + local.get $2 + i32.const 0 + i32.ne + local.tee $3 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.eq + else + local.get $3 + end + if + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + i32.const 1 + i32.add + local.set $0 + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $continue|0 + end + end + local.get $2 + if (result i32) + local.get $0 + i32.load8_u + local.get $1 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $null (; 21 ;) (type $FUNCSIG$v) nop ) ) diff --git a/tests/allocators/tlsf/untouched.wat b/tests/allocators/tlsf/untouched.wat index ba07ee77..eefda937 100644 --- a/tests/allocators/tlsf/untouched.wat +++ b/tests/allocators/tlsf/untouched.wat @@ -1,15 +1,15 @@ (module - (type $iiii_ (func (param i32 i32 i32 i32))) - (type $_ (func)) - (type $iiii (func (param i32 i32 i32) (result i32))) - (type $ii (func (param i32) (result i32))) - (type $ii_ (func (param i32 i32))) - (type $iii_ (func (param i32 i32 i32))) - (type $iii (func (param i32 i32) (result i32))) - (type $i_ (func (param i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$vii (func (param i32 i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32))) (memory $0 1) - (data (i32.const 8) "\16\00\00\00~\00l\00i\00b\00/\00a\00l\00l\00o\00c\00a\00t\00o\00r\00/\00t\00l\00s\00f\00.\00t\00s\00") + (data (i32.const 8) "\01\00\00\00,\00\00\00~\00l\00i\00b\00/\00a\00l\00l\00o\00c\00a\00t\00o\00r\00/\00t\00l\00s\00f\00.\00t\00s\00") (table $0 1 funcref) (elem (i32.const 0) $null) (global $~lib/allocator/tlsf/SL_BITS i32 (i32.const 5)) @@ -29,15 +29,19 @@ (global $~lib/allocator/tlsf/Root.HL_END i32 (i32.const 2912)) (global $~lib/allocator/tlsf/Root.SIZE i32 (i32.const 2916)) (global $~lib/allocator/tlsf/ROOT (mut i32) (i32.const 0)) - (global $~lib/memory/HEAP_BASE i32 (i32.const 56)) + (global $~lib/memory/HEAP_BASE i32 (i32.const 60)) (export "memory" (memory $0)) (export "table" (table $0)) - (export "memory.compare" (func $~lib/memory/memory.compare)) + (export "memory.copy" (func $~lib/memory/memory.copy)) + (export "memory.init" (func $~lib/memory/memory.init)) + (export "memory.drop" (func $~lib/memory/memory.drop)) (export "memory.allocate" (func $~lib/memory/memory.allocate)) (export "memory.free" (func $~lib/memory/memory.free)) (export "memory.reset" (func $~lib/memory/memory.reset)) + (export "memory.repeat" (func $~lib/memory/memory.repeat)) + (export "memory.compare" (func $~lib/memory/memory.compare)) (start $start) - (func $start:~lib/allocator/tlsf (; 1 ;) (type $_) + (func $start:~lib/allocator/tlsf (; 1 ;) (type $FUNCSIG$v) i32.const 1 global.get $~lib/allocator/tlsf/SL_BITS i32.shl @@ -46,90 +50,36 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 122 + i32.const 16 + i32.const 114 i32.const 0 call $~lib/env/abort unreachable end ) - (func $start:assembly/index (; 2 ;) (type $_) + (func $start:assembly/index (; 2 ;) (type $FUNCSIG$v) call $start:~lib/allocator/tlsf ) - (func $~lib/internal/memory/memcmp (; 3 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - local.get $0 - local.get $1 - i32.eq - if - i32.const 0 - return - end - block $break|0 - loop $continue|0 - local.get $2 - i32.const 0 - i32.ne - local.tee $3 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.eq - else - local.get $3 - end - if - block - local.get $2 - i32.const 1 - i32.sub - local.set $2 - local.get $0 - i32.const 1 - i32.add - local.set $0 - local.get $1 - i32.const 1 - i32.add - local.set $1 - end - br $continue|0 - end - end - end - local.get $2 - if (result i32) - local.get $0 - i32.load8_u - local.get $1 - i32.load8_u - i32.sub - else - i32.const 0 - end + (func $~lib/memory/memory.init (; 3 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + unreachable ) - (func $~lib/memory/memory.compare (; 4 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - local.get $0 - local.get $1 - local.get $2 - call $~lib/internal/memory/memcmp + (func $~lib/memory/memory.drop (; 4 ;) (type $FUNCSIG$vi) (param $0 i32) + unreachable ) - (func $~lib/allocator/tlsf/Root#set:tailRef (; 5 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $~lib/allocator/tlsf/Root#set:tailRef (; 5 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) i32.const 0 local.get $1 i32.store offset=2912 ) - (func $~lib/allocator/tlsf/Root#setSLMap (; 6 ;) (type $iii_) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/allocator/tlsf/Root#setSLMap (; 6 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) local.get $1 global.get $~lib/allocator/tlsf/FL_BITS i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 144 + i32.const 16 + i32.const 135 i32.const 4 call $~lib/env/abort unreachable @@ -142,15 +92,15 @@ local.get $2 i32.store offset=4 ) - (func $~lib/allocator/tlsf/Root#setHead (; 7 ;) (type $iiii_) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (func $~lib/allocator/tlsf/Root#setHead (; 7 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) local.get $1 global.get $~lib/allocator/tlsf/FL_BITS i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 167 + i32.const 16 + i32.const 158 i32.const 4 call $~lib/env/abort unreachable @@ -161,8 +111,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 168 + i32.const 16 + i32.const 159 i32.const 4 call $~lib/env/abort unreachable @@ -179,11 +129,11 @@ local.get $3 i32.store offset=96 ) - (func $~lib/allocator/tlsf/Root#get:tailRef (; 8 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/Root#get:tailRef (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) i32.const 0 i32.load offset=2912 ) - (func $~lib/allocator/tlsf/Block#get:right (; 9 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/Block#get:right (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) local.get $0 i32.load @@ -194,8 +144,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 89 + i32.const 16 + i32.const 81 i32.const 4 call $~lib/env/abort unreachable @@ -214,8 +164,8 @@ i32.eqz if (result i32) i32.const 0 - i32.const 8 - i32.const 90 + i32.const 16 + i32.const 82 i32.const 11 call $~lib/env/abort unreachable @@ -223,15 +173,15 @@ local.get $1 end ) - (func $~lib/allocator/tlsf/fls (; 10 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/fls (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 0 i32.ne i32.eqz if i32.const 0 - i32.const 8 - i32.const 428 + i32.const 16 + i32.const 419 i32.const 2 call $~lib/env/abort unreachable @@ -241,15 +191,15 @@ i32.clz i32.sub ) - (func $~lib/allocator/tlsf/Root#getHead (; 11 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#getHead (; 11 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) local.get $1 global.get $~lib/allocator/tlsf/FL_BITS i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 158 + i32.const 16 + i32.const 149 i32.const 4 call $~lib/env/abort unreachable @@ -260,8 +210,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 159 + i32.const 16 + i32.const 150 i32.const 4 call $~lib/env/abort unreachable @@ -277,15 +227,15 @@ i32.add i32.load offset=96 ) - (func $~lib/allocator/tlsf/Root#getSLMap (; 12 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/allocator/tlsf/Root#getSLMap (; 12 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) local.get $1 global.get $~lib/allocator/tlsf/FL_BITS i32.lt_u i32.eqz if i32.const 0 - i32.const 8 - i32.const 138 + i32.const 16 + i32.const 129 i32.const 4 call $~lib/env/abort unreachable @@ -297,7 +247,7 @@ i32.add i32.load offset=4 ) - (func $~lib/allocator/tlsf/Root#remove (; 13 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $~lib/allocator/tlsf/Root#remove (; 13 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -314,8 +264,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 258 + i32.const 16 + i32.const 249 i32.const 4 call $~lib/env/abort unreachable @@ -340,8 +290,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 260 + i32.const 16 + i32.const 251 i32.const 4 call $~lib/env/abort unreachable @@ -442,7 +392,7 @@ end end ) - (func $~lib/allocator/tlsf/Block#get:left (; 14 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/Block#get:left (; 14 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) local.get $0 i32.load @@ -451,8 +401,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 81 + i32.const 16 + i32.const 73 i32.const 4 call $~lib/env/abort unreachable @@ -465,8 +415,8 @@ i32.eqz if (result i32) i32.const 0 - i32.const 8 - i32.const 82 + i32.const 16 + i32.const 74 i32.const 11 call $~lib/env/abort unreachable @@ -474,7 +424,7 @@ local.get $1 end ) - (func $~lib/allocator/tlsf/Root#setJump (; 15 ;) (type $iii_) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/allocator/tlsf/Root#setJump (; 15 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) local.get $1 i32.load global.get $~lib/allocator/tlsf/FREE @@ -482,8 +432,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 334 + i32.const 16 + i32.const 325 i32.const 4 call $~lib/env/abort unreachable @@ -495,8 +445,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 335 + i32.const 16 + i32.const 326 i32.const 4 call $~lib/env/abort unreachable @@ -508,8 +458,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 336 + i32.const 16 + i32.const 327 i32.const 4 call $~lib/env/abort unreachable @@ -520,7 +470,7 @@ local.get $1 i32.store ) - (func $~lib/allocator/tlsf/Root#insert (; 16 ;) (type $ii_) (param $0 i32) (param $1 i32) + (func $~lib/allocator/tlsf/Root#insert (; 16 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -534,8 +484,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 189 + i32.const 16 + i32.const 180 i32.const 4 call $~lib/env/abort unreachable @@ -549,8 +499,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 191 + i32.const 16 + i32.const 182 i32.const 4 call $~lib/env/abort unreachable @@ -575,8 +525,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 193 + i32.const 16 + i32.const 184 i32.const 4 call $~lib/env/abort unreachable @@ -587,8 +537,8 @@ i32.eqz if (result i32) i32.const 0 - i32.const 8 - i32.const 197 + i32.const 16 + i32.const 188 i32.const 23 call $~lib/env/abort unreachable @@ -635,8 +585,8 @@ i32.eqz if (result i32) i32.const 0 - i32.const 8 - i32.const 211 + i32.const 16 + i32.const 202 i32.const 24 call $~lib/env/abort unreachable @@ -653,8 +603,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 213 + i32.const 16 + i32.const 204 i32.const 6 call $~lib/env/abort unreachable @@ -708,8 +658,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 226 + i32.const 16 + i32.const 217 i32.const 4 call $~lib/env/abort unreachable @@ -786,7 +736,7 @@ i32.or call $~lib/allocator/tlsf/Root#setSLMap ) - (func $~lib/allocator/tlsf/Root#addMemory (; 17 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#addMemory (; 17 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -799,8 +749,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 377 + i32.const 16 + i32.const 368 i32.const 4 call $~lib/env/abort unreachable @@ -812,8 +762,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 378 + i32.const 16 + i32.const 369 i32.const 4 call $~lib/env/abort unreachable @@ -825,8 +775,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 379 + i32.const 16 + i32.const 370 i32.const 4 call $~lib/env/abort unreachable @@ -846,8 +796,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 384 + i32.const 16 + i32.const 375 i32.const 6 call $~lib/env/abort unreachable @@ -875,8 +825,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 393 + i32.const 16 + i32.const 384 i32.const 6 call $~lib/env/abort unreachable @@ -939,15 +889,15 @@ call $~lib/allocator/tlsf/Root#insert i32.const 1 ) - (func $~lib/allocator/tlsf/ffs (; 18 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/ffs (; 18 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 0 i32.ne i32.eqz if i32.const 0 - i32.const 8 - i32.const 422 + i32.const 16 + i32.const 413 i32.const 2 call $~lib/env/abort unreachable @@ -955,15 +905,15 @@ local.get $0 i32.ctz ) - (func $~lib/allocator/tlsf/ffs (; 19 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/allocator/tlsf/ffs (; 19 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 i32.const 0 i32.ne i32.eqz if i32.const 0 - i32.const 8 - i32.const 422 + i32.const 16 + i32.const 413 i32.const 2 call $~lib/env/abort unreachable @@ -971,7 +921,7 @@ local.get $0 i32.ctz ) - (func $~lib/allocator/tlsf/Root#search (; 20 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (func $~lib/allocator/tlsf/Root#search (; 20 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -992,8 +942,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 296 + i32.const 16 + i32.const 287 i32.const 4 call $~lib/env/abort unreachable @@ -1088,8 +1038,8 @@ local.get $7 else i32.const 0 - i32.const 8 - i32.const 323 + i32.const 16 + i32.const 314 i32.const 16 call $~lib/env/abort unreachable @@ -1112,7 +1062,7 @@ end local.get $6 ) - (func $~lib/allocator/tlsf/Root#use (; 21 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $~lib/allocator/tlsf/Root#use (; 21 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1125,8 +1075,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 348 + i32.const 16 + i32.const 339 i32.const 4 call $~lib/env/abort unreachable @@ -1145,8 +1095,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 349 + i32.const 16 + i32.const 340 i32.const 4 call $~lib/env/abort unreachable @@ -1158,8 +1108,8 @@ i32.eqz if i32.const 0 - i32.const 8 - i32.const 350 + i32.const 16 + i32.const 341 i32.const 4 call $~lib/env/abort unreachable @@ -1218,8 +1168,8 @@ i32.eqz if (result i32) i32.const 0 - i32.const 8 - i32.const 368 + i32.const 16 + i32.const 359 i32.const 25 call $~lib/env/abort unreachable @@ -1240,7 +1190,7 @@ global.get $~lib/allocator/tlsf/Block.INFO i32.add ) - (func $~lib/allocator/tlsf/__memory_allocate (; 22 ;) (type $ii) (param $0 i32) (result i32) + (func $~lib/memory/memory.allocate (; 22 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) (local $2 i32) (local $3 i32) @@ -1248,297 +1198,1821 @@ (local $5 i32) (local $6 i32) (local $7 i32) - global.get $~lib/allocator/tlsf/ROOT - local.set $1 - local.get $1 - i32.eqz - if - global.get $~lib/memory/HEAP_BASE - i32.const 7 - i32.add - i32.const 7 - i32.const -1 - i32.xor - i32.and + (local $8 i32) + block $~lib/allocator/tlsf/__memory_allocate|inlined.0 (result i32) + local.get $0 + local.set $1 + global.get $~lib/allocator/tlsf/ROOT local.set $2 - current_memory - local.set $3 local.get $2 - global.get $~lib/allocator/tlsf/Root.SIZE - i32.add - i32.const 65535 - i32.add - i32.const 65535 - i32.const -1 - i32.xor - i32.and - i32.const 16 - i32.shr_u - local.set $4 - local.get $4 - local.get $3 - i32.gt_s - local.tee $5 - if (result i32) - local.get $4 - local.get $3 - i32.sub - grow_memory - i32.const 0 - i32.lt_s - else - local.get $5 - end + i32.eqz if - unreachable - end - local.get $2 - local.tee $1 - global.set $~lib/allocator/tlsf/ROOT - local.get $1 - i32.const 0 - call $~lib/allocator/tlsf/Root#set:tailRef - local.get $1 - i32.const 0 - i32.store - block $break|0 - i32.const 0 + global.get $~lib/memory/HEAP_BASE + i32.const 7 + i32.add + i32.const 7 + i32.const -1 + i32.xor + i32.and + local.set $3 + current_memory + local.set $4 + local.get $3 + global.get $~lib/allocator/tlsf/Root.SIZE + i32.add + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u local.set $5 - loop $repeat|0 + local.get $5 + local.get $4 + i32.gt_s + local.tee $6 + if (result i32) local.get $5 - global.get $~lib/allocator/tlsf/FL_BITS - i32.lt_u - i32.eqz - br_if $break|0 - block - local.get $1 - local.get $5 - i32.const 0 - call $~lib/allocator/tlsf/Root#setSLMap - block $break|1 - i32.const 0 - local.set $6 - loop $repeat|1 - local.get $6 - global.get $~lib/allocator/tlsf/SL_SIZE - i32.lt_u - i32.eqz - br_if $break|1 - local.get $1 - local.get $5 - local.get $6 - i32.const 0 - call $~lib/allocator/tlsf/Root#setHead - local.get $6 - i32.const 1 - i32.add - local.set $6 - br $repeat|1 - unreachable - end - unreachable - end - end - local.get $5 - i32.const 1 - i32.add - local.set $5 - br $repeat|0 + local.get $4 + i32.sub + grow_memory + i32.const 0 + i32.lt_s + else + local.get $6 + end + if unreachable end + local.get $3 + local.tee $2 + global.set $~lib/allocator/tlsf/ROOT + local.get $2 + i32.const 0 + call $~lib/allocator/tlsf/Root#set:tailRef + local.get $2 + i32.const 0 + i32.store + block $break|0 + i32.const 0 + local.set $6 + loop $repeat|0 + local.get $6 + global.get $~lib/allocator/tlsf/FL_BITS + i32.lt_u + i32.eqz + br_if $break|0 + block + local.get $2 + local.get $6 + i32.const 0 + call $~lib/allocator/tlsf/Root#setSLMap + block $break|1 + i32.const 0 + local.set $7 + loop $repeat|1 + local.get $7 + global.get $~lib/allocator/tlsf/SL_SIZE + i32.lt_u + i32.eqz + br_if $break|1 + local.get $2 + local.get $6 + local.get $7 + i32.const 0 + call $~lib/allocator/tlsf/Root#setHead + local.get $7 + i32.const 1 + i32.add + local.set $7 + br $repeat|1 + unreachable + end + unreachable + end + end + local.get $6 + i32.const 1 + i32.add + local.set $6 + br $repeat|0 + unreachable + end + unreachable + end + local.get $2 + local.get $3 + global.get $~lib/allocator/tlsf/Root.SIZE + i32.add + i32.const 7 + i32.add + i32.const 7 + i32.const -1 + i32.xor + i32.and + current_memory + i32.const 16 + i32.shl + call $~lib/allocator/tlsf/Root#addMemory + drop + end + local.get $1 + global.get $~lib/allocator/tlsf/Block.MAX_SIZE + i32.gt_u + if unreachable end local.get $1 - local.get $2 - global.get $~lib/allocator/tlsf/Root.SIZE - i32.add i32.const 7 i32.add i32.const 7 i32.const -1 i32.xor i32.and - current_memory - i32.const 16 - i32.shl - call $~lib/allocator/tlsf/Root#addMemory - drop - end - local.get $0 - global.get $~lib/allocator/tlsf/Block.MAX_SIZE - i32.gt_u - if - unreachable - end - local.get $0 - i32.const 7 - i32.add - i32.const 7 - i32.const -1 - i32.xor - i32.and - local.tee $4 - global.get $~lib/allocator/tlsf/Block.MIN_SIZE - local.tee $3 - local.get $4 - local.get $3 - i32.gt_u - select - local.set $0 - local.get $1 - local.get $0 - call $~lib/allocator/tlsf/Root#search - local.set $7 - local.get $7 - i32.eqz - if - current_memory - local.set $4 - local.get $0 - i32.const 65535 - i32.add - i32.const 65535 - i32.const -1 - i32.xor - i32.and - i32.const 16 - i32.shr_u - local.set $3 - local.get $4 - local.tee $2 - local.get $3 local.tee $5 - local.get $2 + global.get $~lib/allocator/tlsf/Block.MIN_SIZE + local.tee $4 local.get $5 - i32.gt_s + local.get $4 + i32.gt_u select - local.set $2 + local.set $1 local.get $2 - grow_memory - i32.const 0 - i32.lt_s + local.get $1 + call $~lib/allocator/tlsf/Root#search + local.set $5 + local.get $5 + i32.eqz if + current_memory + local.set $4 + local.get $1 + i32.const 65535 + i32.add + i32.const 65535 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.shr_u + local.set $3 + local.get $4 + local.tee $6 local.get $3 + local.tee $7 + local.get $6 + local.get $7 + i32.gt_s + select + local.set $6 + local.get $6 grow_memory i32.const 0 i32.lt_s if - unreachable + local.get $3 + grow_memory + i32.const 0 + i32.lt_s + if + unreachable + end end + current_memory + local.set $7 + local.get $2 + local.get $4 + i32.const 16 + i32.shl + local.get $7 + i32.const 16 + i32.shl + call $~lib/allocator/tlsf/Root#addMemory + drop + local.get $2 + local.get $1 + call $~lib/allocator/tlsf/Root#search + local.tee $8 + i32.eqz + if (result i32) + i32.const 0 + i32.const 16 + i32.const 472 + i32.const 12 + call $~lib/env/abort + unreachable + else + local.get $8 + end + local.set $5 end - current_memory - local.set $5 - local.get $1 - local.get $4 - i32.const 16 - i32.shl local.get $5 - i32.const 16 - i32.shl - call $~lib/allocator/tlsf/Root#addMemory - drop + i32.load + global.get $~lib/allocator/tlsf/TAGS + i32.const -1 + i32.xor + i32.and local.get $1 - local.get $0 - call $~lib/allocator/tlsf/Root#search - local.tee $6 + i32.ge_u i32.eqz - if (result i32) + if i32.const 0 - i32.const 8 - i32.const 480 - i32.const 12 + i32.const 16 + i32.const 475 + i32.const 2 call $~lib/env/abort unreachable - else - local.get $6 end - local.set $7 + local.get $2 + local.get $5 + local.get $1 + call $~lib/allocator/tlsf/Root#use end - local.get $7 - i32.load - global.get $~lib/allocator/tlsf/TAGS - i32.const -1 - i32.xor - i32.and - local.get $0 - i32.ge_u - i32.eqz - if - i32.const 0 - i32.const 8 - i32.const 483 - i32.const 2 - call $~lib/env/abort - unreachable - end - local.get $1 - local.get $7 - local.get $0 - call $~lib/allocator/tlsf/Root#use - ) - (func $~lib/memory/memory.allocate (; 23 ;) (type $ii) (param $0 i32) (result i32) - local.get $0 - call $~lib/allocator/tlsf/__memory_allocate return ) - (func $~lib/allocator/tlsf/__memory_free (; 24 ;) (type $i_) (param $0 i32) + (func $~lib/memory/memory.free (; 23 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) + (local $4 i32) local.get $0 + local.set $1 + local.get $1 if global.get $~lib/allocator/tlsf/ROOT - local.set $1 - local.get $1 + local.set $2 + local.get $2 if - local.get $0 + local.get $1 global.get $~lib/allocator/tlsf/Block.INFO i32.sub - local.set $2 - local.get $2 - i32.load local.set $3 local.get $3 + i32.load + local.set $4 + local.get $4 global.get $~lib/allocator/tlsf/FREE i32.and i32.eqz i32.eqz if i32.const 0 - i32.const 8 - i32.const 494 + i32.const 16 + i32.const 488 i32.const 6 call $~lib/env/abort unreachable end - local.get $2 local.get $3 + local.get $4 global.get $~lib/allocator/tlsf/FREE i32.or i32.store + local.get $2 local.get $1 - local.get $0 global.get $~lib/allocator/tlsf/Block.INFO i32.sub call $~lib/allocator/tlsf/Root#insert end end ) - (func $~lib/memory/memory.free (; 25 ;) (type $i_) (param $0 i32) - local.get $0 - call $~lib/allocator/tlsf/__memory_free - return - ) - (func $~lib/allocator/tlsf/__memory_reset (; 26 ;) (type $_) + (func $~lib/memory/memory.reset (; 24 ;) (type $FUNCSIG$v) unreachable ) - (func $~lib/memory/memory.reset (; 27 ;) (type $_) - call $~lib/allocator/tlsf/__memory_reset - return + (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) + block $break|0 + loop $continue|0 + local.get $2 + if (result i32) + local.get $1 + i32.const 3 + i32.and + else + local.get $2 + end + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|0 + end + end + end + local.get $0 + i32.const 3 + i32.and + i32.const 0 + i32.eq + if + block $break|1 + loop $continue|1 + local.get $2 + i32.const 16 + i32.ge_u + if + block + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.get $1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $0 + i32.const 12 + i32.add + local.get $1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|1 + end + end + end + local.get $2 + i32.const 8 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.get $1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + local.get $2 + i32.const 4 + i32.and + if + local.get $0 + local.get $1 + i32.load + i32.store + local.get $0 + i32.const 4 + i32.add + local.set $0 + local.get $1 + i32.const 4 + i32.add + local.set $1 + end + local.get $2 + i32.const 2 + i32.and + if + local.get $0 + local.get $1 + i32.load16_u + i32.store16 + local.get $0 + i32.const 2 + i32.add + local.set $0 + local.get $1 + i32.const 2 + i32.add + local.set $1 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + return + end + local.get $2 + i32.const 32 + i32.ge_u + if + block $break|2 + block $case2|2 + block $case1|2 + block $case0|2 + local.get $0 + i32.const 3 + i32.and + local.set $5 + local.get $5 + i32.const 1 + i32.eq + br_if $case0|2 + local.get $5 + i32.const 2 + i32.eq + br_if $case1|2 + local.get $5 + i32.const 3 + i32.eq + br_if $case2|2 + br $break|2 + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 3 + i32.sub + local.set $2 + block $break|3 + loop $continue|3 + local.get $2 + i32.const 17 + i32.ge_u + if + block + local.get $1 + i32.const 1 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 5 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 9 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 24 + i32.shr_u + local.get $4 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 13 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 24 + i32.shr_u + local.get $3 + i32.const 8 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|3 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 2 + i32.sub + local.set $2 + block $break|4 + loop $continue|4 + local.get $2 + i32.const 18 + i32.ge_u + if + block + local.get $1 + i32.const 2 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 6 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 10 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 16 + i32.shr_u + local.get $4 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 14 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 16 + i32.shr_u + local.get $3 + i32.const 16 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|4 + end + end + end + br $break|2 + unreachable + end + unreachable + end + block + local.get $1 + i32.load + local.set $3 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block $break|5 + loop $continue|5 + local.get $2 + i32.const 19 + i32.ge_u + if + block + local.get $1 + i32.const 3 + i32.add + i32.load + local.set $4 + local.get $0 + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 7 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 4 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 11 + i32.add + i32.load + local.set $4 + local.get $0 + i32.const 8 + i32.add + local.get $3 + i32.const 8 + i32.shr_u + local.get $4 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 15 + i32.add + i32.load + local.set $3 + local.get $0 + i32.const 12 + i32.add + local.get $4 + i32.const 8 + i32.shr_u + local.get $3 + i32.const 24 + i32.shl + i32.or + i32.store + local.get $1 + i32.const 16 + i32.add + local.set $1 + local.get $0 + i32.const 16 + i32.add + local.set $0 + local.get $2 + i32.const 16 + i32.sub + local.set $2 + end + br $continue|5 + end + end + end + br $break|2 + unreachable + end + unreachable + end + end + local.get $2 + i32.const 16 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 8 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 4 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 2 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + local.get $2 + i32.const 1 + i32.and + if + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end ) - (func $start (; 28 ;) (type $_) + (func $~lib/memory/memory.copy (; 26 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $1 + local.get $2 + i32.add + local.get $0 + i32.le_u + local.tee $5 + if (result i32) + local.get $5 + else + local.get $0 + local.get $2 + i32.add + local.get $1 + i32.le_u + end + if + local.get $0 + local.get $1 + local.get $2 + call $~lib/util/memory/memcpy + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|0 + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $2 + i32.const 1 + i32.sub + local.set $2 + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + end + br $continue|0 + end + end + end + block $break|1 + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + end + br $continue|1 + end + end + end + end + block $break|2 + loop $continue|2 + local.get $2 + if + block + block (result i32) + local.get $0 + local.tee $5 + i32.const 1 + i32.add + local.set $0 + local.get $5 + end + block (result i32) + local.get $1 + local.tee $5 + i32.const 1 + i32.add + local.set $1 + local.get $5 + end + i32.load8_u + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + end + br $continue|2 + end + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + block $break|3 + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + block + local.get $2 + i32.eqz + if + br $~lib/util/memory/memmove|inlined.0 + end + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + end + br $continue|3 + end + end + end + block $break|4 + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + block + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + local.get $2 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + end + br $continue|4 + end + end + end + end + block $break|5 + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + end + ) + (func $~lib/memory/memory.repeat (; 27 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + i32.const 0 + local.set $4 + local.get $2 + local.get $3 + i32.mul + local.set $5 + block $break|0 + loop $continue|0 + local.get $4 + local.get $5 + i32.lt_u + if + block + local.get $0 + local.get $4 + i32.add + local.get $1 + local.get $2 + call $~lib/memory/memory.copy + local.get $4 + local.get $2 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + ) + (func $~lib/memory/memory.compare (; 28 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + block $~lib/util/memory/memcmp|inlined.0 (result i32) + local.get $0 + local.set $5 + local.get $1 + local.set $4 + local.get $2 + local.set $3 + local.get $5 + local.get $4 + i32.eq + if + i32.const 0 + br $~lib/util/memory/memcmp|inlined.0 + end + block $break|0 + loop $continue|0 + local.get $3 + i32.const 0 + i32.ne + local.tee $6 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.eq + else + local.get $6 + end + if + block + local.get $3 + i32.const 1 + i32.sub + local.set $3 + local.get $5 + i32.const 1 + i32.add + local.set $5 + local.get $4 + i32.const 1 + i32.add + local.set $4 + end + br $continue|0 + end + end + end + local.get $3 + if (result i32) + local.get $5 + i32.load8_u + local.get $4 + i32.load8_u + i32.sub + else + i32.const 0 + end + end + ) + (func $start (; 29 ;) (type $FUNCSIG$v) call $start:assembly/index ) - (func $null (; 29 ;) (type $_) + (func $null (; 30 ;) (type $FUNCSIG$v) ) ) diff --git a/tests/compiler/new-without-allocator.ts b/tests/compiler/new-without-allocator.ts index ff9548d5..a50aeb61 100644 --- a/tests/compiler/new-without-allocator.ts +++ b/tests/compiler/new-without-allocator.ts @@ -4,3 +4,4 @@ export function test(): i32 { var a = new A(); return 3; } +// Expect error: AS214 diff --git a/tests/compiler/new-without-allocator.untouched.wat b/tests/compiler/new-without-allocator.untouched.wat index 1716c926..e69de29b 100644 --- a/tests/compiler/new-without-allocator.untouched.wat +++ b/tests/compiler/new-without-allocator.untouched.wat @@ -1,107 +0,0 @@ -(module - (type $FUNCSIG$i (func (result i32))) - (type $FUNCSIG$ii (func (param i32) (result i32))) - (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) - (type $FUNCSIG$v (func)) - (import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32))) - (memory $0 1) - (data (i32.const 8) "\02\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00u\00n\00t\00i\00m\00e\00.\00t\00s\00") - (table $0 1 funcref) - (elem (i32.const 0) $null) - (global $~lib/runtime/HEADER_SIZE i32 (i32.const 8)) - (global $~lib/runtime/HEADER_MAGIC i32 (i32.const -1520547049)) - (global $~lib/ASC_NO_ASSERT i32 (i32.const 0)) - (global $~lib/memory/HEAP_BASE i32 (i32.const 48)) - (export "memory" (memory $0)) - (export "table" (table $0)) - (export "test" (func $new-without-allocator/test)) - (func $~lib/runtime/ADJUSTOBLOCK (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - i32.const 1 - i32.const 32 - local.get $0 - global.get $~lib/runtime/HEADER_SIZE - i32.add - i32.const 1 - i32.sub - i32.clz - i32.sub - i32.shl - ) - (func $~lib/memory/memory.allocate (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - unreachable - ) - (func $~lib/runtime/allocate (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) - local.get $0 - call $~lib/runtime/ADJUSTOBLOCK - call $~lib/memory/memory.allocate - local.set $1 - local.get $1 - global.get $~lib/runtime/HEADER_MAGIC - i32.store - local.get $1 - local.get $0 - i32.store offset=4 - local.get $1 - global.get $~lib/runtime/HEADER_SIZE - i32.add - ) - (func $~lib/runtime/register (; 4 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - local.get $0 - global.get $~lib/memory/HEAP_BASE - i32.gt_u - i32.eqz - if - i32.const 0 - i32.const 16 - i32.const 151 - i32.const 4 - call $~lib/env/abort - unreachable - end - local.get $0 - global.get $~lib/runtime/HEADER_SIZE - i32.sub - local.set $2 - local.get $2 - i32.load - global.get $~lib/runtime/HEADER_MAGIC - i32.eq - i32.eqz - if - i32.const 0 - i32.const 16 - i32.const 153 - i32.const 4 - call $~lib/env/abort - unreachable - end - local.get $2 - local.get $1 - i32.store - local.get $0 - ) - (func $new-without-allocator/A#constructor (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - local.get $0 - i32.eqz - if - i32.const 0 - call $~lib/runtime/allocate - i32.const 1 - call $~lib/runtime/register - local.set $0 - end - local.get $0 - ) - (func $new-without-allocator/test (; 6 ;) (type $FUNCSIG$i) (result i32) - (local $0 i32) - i32.const 0 - call $new-without-allocator/A#constructor - local.set $0 - i32.const 3 - ) - (func $null (; 7 ;) (type $FUNCSIG$v) - ) -)