From c420a2a6ab4f17733396d7eddacb6c299f6cbb90 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 5 Jul 2025 21:54:20 +0800 Subject: [PATCH 01/82] remove unused expressions --- src/main/scala/wasm/StagedMiniWasm.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/wasm/StagedMiniWasm.scala b/src/main/scala/wasm/StagedMiniWasm.scala index 2e22e7a7..bfa2082d 100644 --- a/src/main/scala/wasm/StagedMiniWasm.scala +++ b/src/main/scala/wasm/StagedMiniWasm.scala @@ -433,10 +433,10 @@ trait StagedWasmEvaluator extends SAIOps { def push(v: StagedNum)(implicit ctx: Context): Context = { v match { - case I32(v) => NumType(I32Type); "stack-push".reflectCtrlWith[Unit](v) - case I64(v) => NumType(I64Type); "stack-push".reflectCtrlWith[Unit](v) - case F32(v) => NumType(F32Type); "stack-push".reflectCtrlWith[Unit](v) - case F64(v) => NumType(F64Type); "stack-push".reflectCtrlWith[Unit](v) + case I32(v) => "stack-push".reflectCtrlWith[Unit](v) + case I64(v) => "stack-push".reflectCtrlWith[Unit](v) + case F32(v) => "stack-push".reflectCtrlWith[Unit](v) + case F64(v) => "stack-push".reflectCtrlWith[Unit](v) } ctx.push(v.tipe) } From fb2a2c4e203fba7f571b3142ed2f739e6a7ed5ad Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 7 Jul 2025 14:31:16 +0800 Subject: [PATCH 02/82] let's start from the staged miniwasm interpreter --- .../scala/wasm/StagedConcolicMiniWasm.scala | 1170 +++++++++++++++++ 1 file changed, 1170 insertions(+) create mode 100644 src/main/scala/wasm/StagedConcolicMiniWasm.scala diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala new file mode 100644 index 00000000..6b14bcf6 --- /dev/null +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -0,0 +1,1170 @@ +package gensym.wasm.stagedconcolicminiwasm + +import scala.collection.mutable.{ArrayBuffer, HashMap} + +import lms.core.stub.Adapter +import lms.core.virtualize +import lms.macros.SourceContext +import lms.core.stub.{Base, ScalaGenBase, CGenBase} +import lms.core.Backend._ +import lms.core.Backend.{Block => LMSBlock, Const => LMSConst} +import lms.core.Graph + +import gensym.wasm.ast._ +import gensym.wasm.ast.{Const => WasmConst, Block => WasmBlock} +import gensym.wasm.miniwasm.{ModuleInstance} +import gensym.wasm.ast.{Const => WasmConst, Block => WasmBlock} +import gensym.lmsx.{SAIDriver, StringOps, SAIOps, SAICodeGenBase, CppSAIDriver, CppSAICodeGenBase} + +@virtualize +trait StagedWasmEvaluator extends SAIOps { + def module: ModuleInstance + + trait ReturnSite + + trait StagedNum { + def tipe: ValueType = this match { + case I32(_) => NumType(I32Type) + case I64(_) => NumType(I64Type) + case F32(_) => NumType(F32Type) + case F64(_) => NumType(F64Type) + } + + def i: Rep[Num] + } + case class I32(i: Rep[Num]) extends StagedNum + case class I64(i: Rep[Num]) extends StagedNum + case class F32(i: Rep[Num]) extends StagedNum + case class F64(i: Rep[Num]) extends StagedNum + + implicit def toStagedNum(num: Num): StagedNum = { + num match { + case I32V(_) => I32(num) + case I64V(_) => I64(num) + case F32V(_) => F32(num) + case F64V(_) => F64(num) + } + } + + implicit class ValueTypeOps(ty: ValueType) { + def size: Int = ty match { + case NumType(I32Type) => 4 + case NumType(I64Type) => 8 + case NumType(F32Type) => 4 + case NumType(F64Type) => 8 + } + } + + case class Context( + stackTypes: List[ValueType], + frameTypes: List[ValueType] + ) { + def push(ty: ValueType): Context = { + Context(ty :: stackTypes, frameTypes) + } + + def pop(): (ValueType, Context) = { + val (ty :: rest) = stackTypes + (ty, Context(rest, frameTypes)) + } + + def shift(offset: Int, size: Int): Context = { + // Predef.println(s"[DEBUG] Shifting stack by $offset, size $size, $this") + Predef.assert(offset >= 0, s"Context shift offset must be non-negative, get $offset") + if (offset == 0) { + this + } else { + this.copy( + stackTypes = stackTypes.take(size) ++ stackTypes.drop(offset + size) + ) + } + } + } + + type MCont[A] = Unit => A + type Cont[A] = (MCont[A]) => A + type Trail[A] = List[Context => Rep[Cont[A]]] + + // a cache storing the compiled code for each function, to reduce re-compilation + val compileCache = new HashMap[Int, Rep[(MCont[Unit]) => Unit]] + + def makeDummy: Rep[Unit] = "dummy".reflectCtrlWith[Unit]() + + def funHere[A:Manifest,B:Manifest](f: Rep[A] => Rep[B], dummy: Rep[Unit]): Rep[A => B] = { + // to avoid LMS lifting a function, we create a dummy node and read it inside function + fun((x: Rep[A]) => { + "dummy-op".reflectCtrlWith[Unit](dummy) + f(x) + }) + } + + + def eval(insts: List[Instr], + kont: Context => Rep[Cont[Unit]], + mkont: Rep[MCont[Unit]], + trail: Trail[Unit]) + (implicit ctx: Context): Rep[Unit] = { + if (insts.isEmpty) return kont(ctx)(mkont) + + // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") + // Predef.println(s"[DEBUG] Current context: $ctx") + + val (inst, rest) = (insts.head, insts.tail) + inst match { + case Drop => + val (_, newCtx) = Stack.pop() + eval(rest, kont, mkont, trail)(newCtx) + case WasmConst(num) => + val newCtx = Stack.push(num) + eval(rest, kont, mkont, trail)(newCtx) + case LocalGet(i) => + val newCtx = Stack.push(Frames.get(i)) + eval(rest, kont, mkont, trail)(newCtx) + case LocalSet(i) => + val (num, newCtx) = Stack.pop() + Frames.set(i, num)(newCtx) + eval(rest, kont, mkont, trail)(newCtx) + case LocalTee(i) => + val (num, newCtx) = Stack.peek + Frames.set(i, num) + eval(rest, kont, mkont, trail)(newCtx) + case GlobalGet(i) => + val newCtx = Stack.push(Globals(i)) + eval(rest, kont, mkont, trail)(newCtx) + case GlobalSet(i) => + val (value, newCtx) = Stack.pop() + module.globals(i).ty match { + case GlobalType(tipe, true) => Globals(i) = value + case _ => throw new Exception("Cannot set immutable global") + } + eval(rest, kont, mkont, trail)(newCtx) + case Store(StoreOp(align, offset, ty, None)) => + val (value, newCtx1) = Stack.pop() + val (addr, newCtx2) = Stack.pop()(newCtx1) + Memory.storeInt(addr.toInt, offset, value.toInt) + eval(rest, kont, mkont, trail)(newCtx2) + case Nop => eval(rest, kont, mkont, trail) + case Load(LoadOp(align, offset, ty, None, None)) => + val (addr, newCtx1) = Stack.pop() + val value = Memory.loadInt(addr.toInt, offset) + val newCtx2 = Stack.push(Values.I32V(value))(newCtx1) + eval(rest, kont, mkont, trail)(newCtx2) + case MemorySize => ??? + case MemoryGrow => + val (delta, newCtx1) = Stack.pop() + val newCtx2 = Stack.push(Values.I32V(Memory.grow(delta.toInt)))(newCtx1) + eval(rest, kont, mkont, trail)(newCtx2) + case MemoryFill => ??? + case Unreachable => unreachable() + case Test(op) => + val (v, newCtx1) = Stack.pop() + val newCtx2 = Stack.push(evalTestOp(op, v))(newCtx1) + eval(rest, kont, mkont, trail)(newCtx2) + case Unary(op) => + val (v, newCtx1) = Stack.pop() + val newCtx2 = Stack.push(evalUnaryOp(op, v))(newCtx1) + eval(rest, kont, mkont, trail)(newCtx2) + case Binary(op) => + val (v2, newCtx1) = Stack.pop() + val (v1, newCtx2) = Stack.pop()(newCtx1) + val newCtx3 = Stack.push(evalBinOp(op, v1, v2))(newCtx2) + eval(rest, kont, mkont, trail)(newCtx3) + case Compare(op) => + val (v2, newCtx1) = Stack.pop() + val (v1, newCtx2) = Stack.pop()(newCtx1) + val newCtx3 = Stack.push(evalRelOp(op, v1, v2))(newCtx2) + eval(rest, kont, mkont, trail)(newCtx3) + case WasmBlock(ty, inner) => + // no need to modify the stack when entering a block + // the type system guarantees that we will never take more than the input size from the stack + val funcTy = ty.funcType + val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val dummy = makeDummy + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Exiting the block, stackSize =", Stack.size) + val offset = restCtx.stackTypes.size - exitSize + val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) + eval(rest, kont, mk, trail)(newRestCtx) + }) + eval(inner, restK _, mkont, restK _ :: trail) + case Loop(ty, inner) => + val funcTy = ty.funcType + val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val dummy = makeDummy + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Exiting the loop, stackSize =", Stack.size) + val offset = restCtx.stackTypes.size - exitSize + val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) + eval(rest, kont, mk, trail)(newRestCtx) + }) + val enterSize = ctx.stackTypes.size + def loop(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Entered the loop, stackSize =", Stack.size) + val offset = restCtx.stackTypes.size - enterSize + val newRestCtx = Stack.shift(offset, funcTy.inps.size)(restCtx) + eval(inner, restK _, mk, loop _ :: trail)(newRestCtx) + }) + loop(ctx)(mkont) + case If(ty, thn, els) => + val funcTy = ty.funcType + val (cond, newCtx) = Stack.pop() + val exitSize = newCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size + // TODO: can we avoid code duplication here? + val dummy = makeDummy + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Exiting the if, stackSize =", Stack.size) + val offset = restCtx.stackTypes.size - exitSize + val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) + eval(rest, kont, mk, trail)(newRestCtx) + }) + if (cond.toInt != 0) { + eval(thn, restK _, mkont, restK _ :: trail)(newCtx) + } else { + eval(els, restK _, mkont, restK _ :: trail)(newCtx) + } + () + case Br(label) => + info(s"Jump to $label") + trail(label)(ctx)(mkont) + case BrIf(label) => + val (cond, newCtx) = Stack.pop() + info(s"The br_if(${label})'s condition is ", cond.toInt) + if (cond.toInt != 0) { + info(s"Jump to $label") + trail(label)(newCtx)(mkont) + } else { + info(s"Continue") + eval(rest, kont, mkont, trail)(newCtx) + } + () + case BrTable(labels, default) => + val (cond, newCtx) = Stack.pop() + def aux(choices: List[Int], idx: Int): Rep[Unit] = { + if (choices.isEmpty) trail(default)(newCtx)(mkont) + else { + if (cond.toInt == idx) trail(choices.head)(newCtx)(mkont) + else aux(choices.tail, idx + 1) + } + } + aux(labels, 0) + case Return => trail.last(ctx)(mkont) + case Call(f) => evalCall(rest, kont, mkont, trail, f, false) + case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true) + case _ => + val todo = "todo-op".reflectCtrlWith[Unit]() + eval(rest, kont, mkont, trail) + } + } + + def forwardKont: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => mk(())) + + + def evalCall(rest: List[Instr], + kont: Context => Rep[Cont[Unit]], + mkont: Rep[MCont[Unit]], + trail: Trail[Unit], + funcIndex: Int, + isTail: Boolean) + (implicit ctx: Context): Rep[Unit] = { + module.funcs(funcIndex) match { + case FuncDef(_, FuncBodyDef(ty, _, bodyLocals, body)) => + val locals = bodyLocals ++ ty.inps + val callee = + if (compileCache.contains(funcIndex)) { + compileCache(funcIndex) + } else { + val callee = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Entered the function at $funcIndex, stackSize =", Stack.size) + // we can do some check here to ensure the function returns correct size of stack + eval(body, (_: Context) => forwardKont, mk, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) + }) + compileCache(funcIndex) = callee + callee + } + // Predef.println(s"[DEBUG] locals size: ${locals.size}") + val (args, newCtx) = Stack.take(ty.inps.size) + if (isTail) { + // when tail call, return to the caller's return continuation + Frames.popFrame(ctx.frameTypes.size) + Frames.pushFrame(locals) + Frames.putAll(args) + callee(mkont) + } else { + // We make a new trail by `restK`, since function creates a new block to escape + // (more or less like `return`) + val restK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Exiting the function at $funcIndex, stackSize =", Stack.size) + Frames.popFrame(locals.size) + eval(rest, kont, mk, trail)(newCtx.copy(stackTypes = ty.out.reverse ++ ctx.stackTypes.drop(ty.inps.size))) + }) + val dummy = makeDummy + val newMKont: Rep[MCont[Unit]] = funHere((_u: Rep[Unit]) => { + restK(mkont) + }, dummy) + Frames.pushFrame(locals) + Frames.putAll(args) + callee(newMKont) + } + case Import("console", "log", _) + | Import("spectest", "print_i32", _) => + //println(s"[DEBUG] current stack: $stack") + val (v, newCtx) = Stack.pop() + println(v.toInt) + eval(rest, kont, mkont, trail)(newCtx) + case Import(_, _, _) => throw new Exception(s"Unknown import at $funcIndex") + case _ => throw new Exception(s"Definition at $funcIndex is not callable") + } + } + + def evalTestOp(op: TestOp, value: StagedNum): StagedNum = op match { + case Eqz(_) => Values.I32V(if (value.toInt == 0) 1 else 0) + } + + def evalUnaryOp(op: UnaryOp, value: StagedNum): StagedNum = op match { + case Clz(_) => value.clz() + case Ctz(_) => value.ctz() + case Popcnt(_) => value.popcnt() + case _ => ??? + } + + def evalBinOp(op: BinOp, v1: StagedNum, v2: StagedNum): StagedNum = op match { + case Add(_) => v1 + v2 + case Mul(_) => v1 * v2 + case Sub(_) => v1 - v2 + case Shl(_) => v1 << v2 + // case ShrS(_) => v1 >> v2 // TODO: signed shift right + case ShrU(_) => v1 >> v2 + case And(_) => v1 & v2 + case DivS(_) => v1 / v2 + case DivU(_) => v1 / v2 + case _ => + throw new Exception(s"Unknown binary operation $op") + } + + def evalRelOp(op: RelOp, v1: StagedNum, v2: StagedNum): StagedNum = op match { + case Eq(_) => v1 numEq v2 + case Ne(_) => v1 numNe v2 + case LtS(_) => v1 < v2 + case LtU(_) => v1 ltu v2 + case GtS(_) => v1 > v2 + case GtU(_) => v1 gtu v2 + case LeS(_) => v1 <= v2 + case LeU(_) => v1 leu v2 + case GeS(_) => v1 >= v2 + case GeU(_) => v1 geu v2 + case _ => ??? + } + + def evalTop(mkont: Rep[MCont[Unit]], main: Option[String]): Rep[Unit] = { + val funBody: FuncBodyDef = main match { + case Some(func_name) => + module.defs.flatMap({ + case Export(`func_name`, ExportFunc(fid)) => + Predef.println(s"Now compiling start with function $main") + module.funcs(fid) match { + case FuncDef(_, body@FuncBodyDef(_,_,_,_)) => Some(body) + case _ => throw new Exception("Entry function has no concrete body") + } + case _ => None + }).head + case None => + val startIds = module.defs.flatMap { + case Start(id) => Some(id) + case _ => None + } + val startId = startIds.headOption.getOrElse { throw new Exception("No start function") } + module.funcs(startId) match { + case FuncDef(_, body@FuncBodyDef(_,_,_,_)) => body + case _ => + throw new Exception("Entry function has no concrete body") + } + } + val (instrs, locals) = (funBody.body, funBody.locals) + Stack.initialize() + Frames.pushFrame(locals) + eval(instrs, (_: Context) => forwardKont, mkont, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) + Frames.popFrame(locals.size) + } + + def evalTop(main: Option[String], printRes: Boolean = false): Rep[Unit] = { + val haltK: Rep[Unit] => Rep[Unit] = (_) => { + info("Exiting the program...") + if (printRes) { + Stack.print() + } + "no-op".reflectCtrlWith[Unit]() + } + val temp: Rep[MCont[Unit]] = topFun(haltK) + evalTop(temp, main) + } + + // stack operations + object Stack { + def shift(offset: Int, size: Int)(ctx: Context): Context = { + if (offset > 0) { + "stack-shift".reflectCtrlWith[Unit](offset, size) + } + ctx.shift(offset, size) + } + + def initialize(): Rep[Unit] = { + "stack-init".reflectCtrlWith[Unit]() + } + + def pop()(implicit ctx: Context): (StagedNum, Context) = { + val (ty, newContext) = ctx.pop() + val num = ty match { + case NumType(I32Type) => I32("stack-pop".reflectCtrlWith[Num]()) + case NumType(I64Type) => I64("stack-pop".reflectCtrlWith[Num]()) + case NumType(F32Type) => F32("stack-pop".reflectCtrlWith[Num]()) + case NumType(F32Type) => F64("stack-pop".reflectCtrlWith[Num]()) + } + (num, newContext) + } + + def peek(implicit ctx: Context): (StagedNum, Context) = { + val ty = ctx.stackTypes.head + val num = ty match { + case NumType(I32Type) => I32("stack-peek".reflectCtrlWith[Num]()) + case NumType(I64Type) => I64("stack-peek".reflectCtrlWith[Num]()) + case NumType(F32Type) => F32("stack-peek".reflectCtrlWith[Num]()) + case NumType(F32Type) => F64("stack-peek".reflectCtrlWith[Num]()) + } + (num, ctx) + } + + def push(v: StagedNum)(implicit ctx: Context): Context = { + v match { + case I32(v) => "stack-push".reflectCtrlWith[Unit](v) + case I64(v) => "stack-push".reflectCtrlWith[Unit](v) + case F32(v) => "stack-push".reflectCtrlWith[Unit](v) + case F64(v) => "stack-push".reflectCtrlWith[Unit](v) + } + ctx.push(v.tipe) + } + + def take(n: Int)(implicit ctx: Context): (List[StagedNum], Context) = n match { + case 0 => (Nil, ctx) + case n => + val (v, newCtx1) = pop() + val (rest, newCtx2) = take(n - 1) + (v::rest, newCtx2) + } + + def drop(n: Int)(implicit ctx: Context): Context = { + take(n)._2 + } + + def shift(offset: Rep[Int], size: Rep[Int]): Rep[Unit] = { + if (offset > 0) { + "stack-shift".reflectCtrlWith[Unit](offset, size) + } + } + + def print(): Rep[Unit] = { + "stack-print".reflectCtrlWith[Unit]() + } + + def size: Rep[Int] = { + "stack-size".reflectCtrlWith[Int]() + } + } + + object Frames { + def get(i: Int)(implicit ctx: Context): StagedNum = { + // val offset = ctx.frameTypes.take(i).map(_.size).sum + ctx.frameTypes(i) match { + case NumType(I32Type) => I32("frame-get".reflectCtrlWith[Num](i)) + case NumType(I64Type) => I64("frame-get".reflectCtrlWith[Num](i)) + case NumType(F32Type) => F32("frame-get".reflectCtrlWith[Num](i)) + case NumType(F64Type) => F64("frame-get".reflectCtrlWith[Num](i)) + } + } + + def set(i: Int, v: StagedNum)(implicit ctx: Context): Rep[Unit] = { + // val offset = ctx.frameTypes.take(i).map(_.size).sum + v match { + case I32(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case I64(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case F32(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case F64(v) => "frame-set".reflectCtrlWith[Unit](i, v) + } + } + + def pushFrame(locals: List[ValueType]): Rep[Unit] = { + // Predef.println(s"[DEBUG] push frame: $locals") + val size = locals.size + "frame-push".reflectCtrlWith[Unit](size) + } + + def popFrame(size: Int): Rep[Unit] = { + "frame-pop".reflectCtrlWith[Unit](size) + } + + def putAll(args: List[StagedNum])(implicit ctx: Context): Rep[Unit] = { + for ((arg, i) <- args.view.reverse.zipWithIndex) { + Frames.set(i, arg) + } + } + } + + object Memory { + def storeInt(base: Rep[Int], offset: Int, value: Rep[Int]): Rep[Unit] = { + "memory-store-int".reflectCtrlWith[Unit](base, offset, value) + } + + def loadInt(base: Rep[Int], offset: Int): Rep[Int] = { + "memory-load-int".reflectCtrlWith[Int](base, offset) + } + + def grow(delta: Rep[Int]): Rep[Int] = { + "memory-grow".reflectCtrlWith[Int](delta) + } + } + + // call unreachable + def unreachable(): Rep[Unit] = { + "unreachable".reflectCtrlWith[Unit]() + } + + def info(xs: Rep[_]*): Rep[Unit] = { + "info".reflectCtrlWith[Unit](xs: _*) + } + + // runtime values + object Values { + def I32V(i: Rep[Int]): StagedNum = { + I32("I32V".reflectCtrlWith[Num](i)) + } + + def I64V(i: Rep[Long]): StagedNum = { + I64("I64V".reflectCtrlWith[Num](i)) + } + } + + // global read/write + object Globals { + def apply(i: Int): StagedNum = { + module.globals(i).ty match { + case GlobalType(NumType(I32Type), _) => I32("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(I64Type), _) => I64("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(F32Type), _) => F32("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(F64Type), _) => F64("global-get".reflectCtrlWith[Num](i)) + } + } + + def update(i: Int, v: StagedNum): Rep[Unit] = { + module.globals(i).ty match { + case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i) + case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i) + case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i) + case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i) + } + } + } + + // runtime Num type + implicit class StagedNumOps(num: StagedNum) { + + def toInt: Rep[Int] = "num-to-int".reflectCtrlWith[Int](num.i) + + def clz(): StagedNum = num match { + case I32(i) => I32("clz".reflectCtrlWith[Num](i)) + case I64(i) => I64("clz".reflectCtrlWith[Num](i)) + } + + def ctz(): StagedNum = num match { + case I32(i) => I32("ctz".reflectCtrlWith[Num](i)) + case I64(i) => I64("ctz".reflectCtrlWith[Num](i)) + } + + def popcnt(): StagedNum = num match { + case I32(i) => I32("popcnt".reflectCtrlWith[Num](i)) + case I64(i) => I64("popcnt".reflectCtrlWith[Num](i)) + } + + def +(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-add".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-add".reflectCtrlWith[Num](x, y)) + case (F32(x), F32(y)) => F32("binary-add".reflectCtrlWith[Num](x, y)) + case (F64(x), F64(y)) => F64("binary-add".reflectCtrlWith[Num](x, y)) + } + } + + def -(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-sub".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-sub".reflectCtrlWith[Num](x, y)) + case (F32(x), F32(y)) => F32("binary-sub".reflectCtrlWith[Num](x, y)) + case (F64(x), F64(y)) => F64("binary-sub".reflectCtrlWith[Num](x, y)) + } + } + + def *(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-mul".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-mul".reflectCtrlWith[Num](x, y)) + case (F32(x), F32(y)) => F32("binary-mul".reflectCtrlWith[Num](x, y)) + case (F64(x), F64(y)) => F64("binary-mul".reflectCtrlWith[Num](x, y)) + } + } + + def /(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-div".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-div".reflectCtrlWith[Num](x, y)) + case (F32(x), F32(y)) => F32("binary-div".reflectCtrlWith[Num](x, y)) + case (F64(x), F64(y)) => F64("binary-div".reflectCtrlWith[Num](x, y)) + } + } + + def <<(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-shl".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-shl".reflectCtrlWith[Num](x, y)) + } + } + + def >>(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-shr".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-shr".reflectCtrlWith[Num](x, y)) + } + } + + def &(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("binary-and".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I64("binary-and".reflectCtrlWith[Num](x, y)) + } + } + + def numEq(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-eq".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-eq".reflectCtrlWith[Num](x, y)) + } + } + + def numNe(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-ne".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-ne".reflectCtrlWith[Num](x, y)) + } + } + + def <(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-lt".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-lt".reflectCtrlWith[Num](x, y)) + } + } + + def ltu(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-ltu".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-ltu".reflectCtrlWith[Num](x, y)) + } + } + + def >(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-gt".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-gt".reflectCtrlWith[Num](x, y)) + } + } + + def gtu(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-gtu".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-gtu".reflectCtrlWith[Num](x, y)) + } + } + + def <=(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-le".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-le".reflectCtrlWith[Num](x, y)) + } + } + + def leu(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-leu".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-leu".reflectCtrlWith[Num](x, y)) + } + } + + def >=(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-ge".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-ge".reflectCtrlWith[Num](x, y)) + } + } + + def geu(rhs: StagedNum): StagedNum = { + (num, rhs) match { + case (I32(x), I32(y)) => I32("relation-geu".reflectCtrlWith[Num](x, y)) + case (I64(x), I64(y)) => I32("relation-geu".reflectCtrlWith[Num](x, y)) + } + } + } +} + +trait StagedWasmScalaGen extends ScalaGenBase with SAICodeGenBase { + override def mayInline(n: Node): Boolean = n match { + case Node(s, "stack-pop", _, _) => false + case _ => super.mayInline(n) + } + + override def traverse(n: Node): Unit = n match { + case Node(_, "stack-drop", List(n), _) => + emit("Stack.drop("); shallow(n); emit(")\n") + case Node(_, "stack-reset", List(n), _) => + emit("Stack.reset("); shallow(n); emit(")\n") + case Node(_, "stack-init", _, _) => + emit("Stack.initialize()\n") + case Node(_, "stack-print", _, _) => + emit("Stack.print()\n") + case Node(_, "frame-push", List(i), _) => + emit("Frames.pushFrame("); shallow(i); emit(")\n") + case Node(_, "frame-pop", List(i), _) => + emit("Frames.popFrame("); shallow(i); emit(")\n") + case Node(_, "frame-putAll", List(args), _) => + emit("Frames.putAll("); shallow(args); emit(")\n") + case Node(_, "frame-set", List(i, value), _) => + emit("Frames.set("); shallow(i); emit(", "); shallow(value); emit(")\n") + case Node(_, "global-set", List(i, value), _) => + emit("Global.globalSet("); shallow(i); emit(", "); shallow(value); emit(")\n") + case _ => super.traverse(n) + } + + // code generation for pure nodes + override def shallow(n: Node): Unit = n match { + case Node(_, "frame-get", List(i), _) => + emit("Frames.get("); shallow(i); emit(")") + case Node(_, "frame-pop", List(i), _) => + emit("Frames.popFrame("); shallow(i); emit(")") + case Node(_, "stack-push", List(value), _) => + emit("Stack.push("); shallow(value); emit(")") + case Node(_, "stack-pop", _, _) => + emit("Stack.pop()") + case Node(_, "stack-peek", _, _) => + emit("Stack.peek") + case Node(_, "stack-take", List(n), _) => + emit("Stack.take("); shallow(n); emit(")") + case Node(_, "stack-size", _, _) => + emit("Stack.size") + case Node(_, "global-get", List(i), _) => + emit("Global.globalGet("); shallow(i); emit(")") + case Node(_, "binary-add", List(lhs, rhs), _) => + shallow(lhs); emit(" + "); shallow(rhs) + case Node(_, "binary-sub", List(lhs, rhs), _) => + shallow(lhs); emit(" - "); shallow(rhs) + case Node(_, "binary-mul", List(lhs, rhs), _) => + shallow(lhs); emit(" * "); shallow(rhs) + case Node(_, "binary-div", List(lhs, rhs), _) => + shallow(lhs); emit(" / "); shallow(rhs) + case Node(_, "binary-shl", List(lhs, rhs), _) => + shallow(lhs); emit(" << "); shallow(rhs) + case Node(_, "binary-shr", List(lhs, rhs), _) => + shallow(lhs); emit(" >> "); shallow(rhs) + case Node(_, "binary-and", List(lhs, rhs), _) => + shallow(lhs); emit(" & "); shallow(rhs) + case Node(_, "relation-eq", List(lhs, rhs), _) => + shallow(lhs); emit(" == "); shallow(rhs) + case Node(_, "relation-ne", List(lhs, rhs), _) => + shallow(lhs); emit(" != "); shallow(rhs) + case Node(_, "relation-lt", List(lhs, rhs), _) => + shallow(lhs); emit(" < "); shallow(rhs) + case Node(_, "relation-ltu", List(lhs, rhs), _) => + shallow(lhs); emit(" < "); shallow(rhs) + case Node(_, "relation-gt", List(lhs, rhs), _) => + shallow(lhs); emit(" > "); shallow(rhs) + case Node(_, "relation-gtu", List(lhs, rhs), _) => + shallow(lhs); emit(" > "); shallow(rhs) + case Node(_, "relation-le", List(lhs, rhs), _) => + shallow(lhs); emit(" <= "); shallow(rhs) + case Node(_, "relation-leu", List(lhs, rhs), _) => + shallow(lhs); emit(" <= "); shallow(rhs) + case Node(_, "relation-ge", List(lhs, rhs), _) => + shallow(lhs); emit(" >= "); shallow(rhs) + case Node(_, "relation-geu", List(lhs, rhs), _) => + shallow(lhs); emit(" >= "); shallow(rhs) + case Node(_, "num-to-int", List(num), _) => + shallow(num); emit(".toInt") + case Node(_, "no-op", _, _) => + emit("()") + case _ => super.shallow(n) + } +} + +trait WasmToScalaCompilerDriver[A, B] + extends SAIDriver[A, B] with StagedWasmEvaluator { q => + override val codegen = new StagedWasmScalaGen { + val IR: q.type = q + import IR._ + override def remap(m: Manifest[_]): String = { + if (m.toString.endsWith("Stack")) "Stack" + else if(m.toString.endsWith("Frame")) "Frame" + else super.remap(m) + } + } + + override val prelude = + """ +object Prelude { + sealed abstract class Num { + def +(that: Num): Num = (this, that) match { + case (I32V(x), I32V(y)) => I32V(x + y) + case (I64V(x), I64V(y)) => I64V(x + y) + case _ => throw new RuntimeException("Invalid addition") + } + + def -(that: Num): Num = (this, that) match { + case (I32V(x), I32V(y)) => I32V(x - y) + case (I64V(x), I64V(y)) => I64V(x - y) + case _ => throw new RuntimeException("Invalid subtraction") + } + + def !=(that: Num): Num = (this, that) match { + case (I32V(x), I32V(y)) => I32V(if (x != y) 1 else 0) + case (I64V(x), I64V(y)) => I32V(if (x != y) 1 else 0) + case _ => throw new RuntimeException("Invalid inequality") + } + + def toInt: Int = this match { + case I32V(i) => i + case I64V(i) => i.toInt + } + } + case class I32V(i: Int) extends Num + case class I64V(i: Long) extends Num + +object Stack { + private val buffer = new scala.collection.mutable.ArrayBuffer[Num]() + def push(v: Num): Unit = buffer.append(v) + def pop(): Num = { + buffer.remove(buffer.size - 1) + } + def peek: Num = { + buffer.last + } + def size: Int = buffer.size + def drop(n: Int): Unit = { + buffer.remove(buffer.size - n, n) + } + def take(n: Int): List[Num] = { + val xs = buffer.takeRight(n).toList + drop(n) + xs + } + def reset(size: Int): Unit = { + info(s"Reset stack to size $size") + while (buffer.size > size) { + buffer.remove(buffer.size - 1) + } + } + def initialize(): Unit = buffer.clear() + def print(): Unit = { + println("Stack: " + buffer.mkString(", ")) + } +} + + class Frame(val size: Int) { + private val data = new Array[Num](size) + def apply(i: Int): Num = { + info(s"frame(${i}) is ${data(i)}") + data(i) + } + def update(i: Int, v: Num): Unit = { + info(s"set frame(${i}) to ${v}") + data(i) = v + } + def putAll(xs: List[Num]): Unit = { + for (i <- 0 until xs.size) { + data(i) = xs(i) + } + } + override def toString: String = { + "Frame(" + data.mkString(", ") + ")" + } + } + + object Frames { + private var frames = List[Frame]() + def pushFrame(size: Int): Unit = { + frames = new Frame(size) :: frames + } + def popFrame(): Unit = { + frames = frames.tail + } + def top: Frame = frames.head + def set(i: Int, v: Num): Unit = { + top(i) = v + } + def get(i: Int): Num = { + top(i) + } + } + + object Global { + // TODO: create global with specific size + private val globals = new Array[Num](10) + def globalGet(i: Int): Num = globals(i) + def globalSet(i: Int, v: Num): Unit = globals(i) = v + } + + def info(xs: Any*): Unit = { + if (System.getenv("DEBUG") != null) { + println("[INFO] " + xs.mkString(" ")) + } + } +} +import Prelude._ + + +object Main { + def main(args: Array[String]): Unit = { + val snippet = new Snippet() + snippet(()) + } +} +""" +} + + +object WasmToScalaCompiler { + def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean = false): String = { + println(s"Now compiling wasm module with entry function $main") + val code = new WasmToScalaCompilerDriver[Unit, Unit] { + def module: ModuleInstance = moduleInst + def snippet(x: Rep[Unit]): Rep[Unit] = { + evalTop(main, printRes) + } + } + code.code + } +} + +trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { + // clear include path and headers by first + includePaths.clear() + headers.clear() + + registerHeader("headers", "\"wasm.hpp\"") + registerHeader("") + registerHeader("") + registerHeader("") + registerHeader("") + + override def mayInline(n: Node): Boolean = n match { + case Node(_, "stack-pop", _, _) + | Node(_, "stack-peek", _, _) + => false + case _ => super.mayInline(n) + } + + override def remap(m: Manifest[_]): String = { + if (m.toString.endsWith("Num")) "Num" + else if (m.toString.endsWith("Frame")) "Frame" + else if (m.toString.endsWith("Stack")) "Stack" + else if (m.toString.endsWith("Global")) "Global" + else if (m.toString.endsWith("I32V")) "I32V" + else if (m.toString.endsWith("I64V")) "I64V" + else super.remap(m) + } + + // for now, the traverse/shallow is same as the scala backend's + override def traverse(n: Node): Unit = n match { + case Node(_, "stack-push", List(value), _) => + emit("Stack.push("); shallow(value); emit(");\n") + case Node(_, "stack-drop", List(n), _) => + emit("Stack.drop("); shallow(n); emit(");\n") + case Node(_, "stack-init", _, _) => + emit("Stack.initialize();\n") + case Node(_, "stack-print", _, _) => + emit("Stack.print();\n") + case Node(_, "frame-push", List(i), _) => + emit("Frames.pushFrame("); shallow(i); emit(");\n") + case Node(_, "frame-pop", List(i), _) => + emit("Frames.popFrame("); shallow(i); emit(");\n") + case Node(_, "frame-putAll", List(args), _) => + emit("Frames.putAll("); shallow(args); emit(");\n") + case Node(_, "frame-set", List(i, value), _) => + emit("Frames.set("); shallow(i); emit(", "); shallow(value); emit(");\n") + case Node(_, "global-set", List(i, value), _) => + emit("Global.globalSet("); shallow(i); emit(", "); shallow(value); emit(");\n") + // Note: The following code is copied from the traverse of CppBackend.scala, try to avoid duplicated code + case n @ Node(f, "λ", (b: LMSBlock)::LMSConst(0)::rest, _) => + // TODO: Is a leading block followed by 0 a hint for top function? + super.traverse(n) + case n @ Node(f, "λ", (b: LMSBlock)::rest, _) => + val retType = remap(typeBlockRes(b.res)) + val argTypes = b.in.map(a => remap(typeMap(a))).mkString(", ") + emitln(s"std::function<$retType(${argTypes})> ${quote(f)};") + emit(quote(f)); emit(" = ") + quoteTypedBlock(b, false, true, capture = "&") + emitln(";") + case _ => super.traverse(n) + } + + // code generation for pure nodes + override def shallow(n: Node): Unit = n match { + case Node(_, "frame-get", List(i), _) => + emit("Frames.get("); shallow(i); emit(")") + case Node(_, "stack-drop", List(n), _) => + emit("Stack.drop("); shallow(n); emit(")") + case Node(_, "stack-push", List(value), _) => + emit("Stack.push("); shallow(value); emit(")") + case Node(_, "stack-shift", List(offset, size), _) => + emit("Stack.shift("); shallow(offset); emit(", "); shallow(size); emit(")") + case Node(_, "stack-pop", _, _) => + emit("Stack.pop()") + case Node(_, "frame-pop", List(i), _) => + emit("Frames.popFrame("); shallow(i); emit(")") + case Node(_, "stack-peek", _, _) => + emit("Stack.peek()") + case Node(_, "stack-take", List(n), _) => + emit("Stack.take("); shallow(n); emit(")") + case Node(_, "slice-reverse", List(slice), _) => + shallow(slice); emit(".reverse") + case Node(_, "memory-store-int", List(base, offset, value), _) => + emit("Memory.storeInt("); shallow(base); emit(", "); shallow(offset); emit(", "); shallow(value); emit(")") + case Node(_, "memory-load-int", List(base, offset), _) => + emit("Memory.loadInt("); shallow(base); emit(", "); shallow(offset); emit(")") + case Node(_, "memory-grow", List(delta), _) => + emit("Memory.grow("); shallow(delta); emit(")") + case Node(_, "stack-size", _, _) => + emit("Stack.size()") + case Node(_, "global-get", List(i), _) => + emit("Global.globalGet("); shallow(i); emit(")") + case Node(_, "binary-add", List(lhs, rhs), _) => + shallow(lhs); emit(" + "); shallow(rhs) + case Node(_, "binary-sub", List(lhs, rhs), _) => + shallow(lhs); emit(" - "); shallow(rhs) + case Node(_, "binary-mul", List(lhs, rhs), _) => + shallow(lhs); emit(" * "); shallow(rhs) + case Node(_, "binary-div", List(lhs, rhs), _) => + shallow(lhs); emit(" / "); shallow(rhs) + case Node(_, "binary-shl", List(lhs, rhs), _) => + shallow(lhs); emit(" << "); shallow(rhs) + case Node(_, "binary-shr", List(lhs, rhs), _) => + shallow(lhs); emit(" >> "); shallow(rhs) + case Node(_, "binary-and", List(lhs, rhs), _) => + shallow(lhs); emit(" & "); shallow(rhs) + case Node(_, "relation-eq", List(lhs, rhs), _) => + shallow(lhs); emit(" == "); shallow(rhs) + case Node(_, "relation-ne", List(lhs, rhs), _) => + shallow(lhs); emit(" != "); shallow(rhs) + case Node(_, "relation-lt", List(lhs, rhs), _) => + shallow(lhs); emit(" < "); shallow(rhs) + case Node(_, "relation-ltu", List(lhs, rhs), _) => + shallow(lhs); emit(" < "); shallow(rhs) + case Node(_, "relation-gt", List(lhs, rhs), _) => + shallow(lhs); emit(" > "); shallow(rhs) + case Node(_, "relation-gtu", List(lhs, rhs), _) => + shallow(lhs); emit(" > "); shallow(rhs) + case Node(_, "relation-le", List(lhs, rhs), _) => + shallow(lhs); emit(" <= "); shallow(rhs) + case Node(_, "relation-leu", List(lhs, rhs), _) => + shallow(lhs); emit(" <= "); shallow(rhs) + case Node(_, "relation-ge", List(lhs, rhs), _) => + shallow(lhs); emit(" >= "); shallow(rhs) + case Node(_, "relation-geu", List(lhs, rhs), _) => + shallow(lhs); emit(" >= "); shallow(rhs) + case Node(_, "num-to-int", List(num), _) => + shallow(num); emit(".toInt()") + case Node(_, "dummy", _, _) => emit("std::monostate()") + case Node(_, "dummy-op", _, _) => emit("std::monostate()") + case Node(_, "no-op", _, _) => + emit("std::monostate()") + case _ => super.shallow(n) + } + + override def registerTopLevelFunction(id: String, streamId: String = "general")(f: => Unit) = + if (!registeredFunctions(id)) { + //if (ongoingFun(streamId)) ??? + //ongoingFun += streamId + registeredFunctions += id + withStream(functionsStreams.getOrElseUpdate(id, { + val functionsStream = new java.io.ByteArrayOutputStream() + val functionsWriter = new java.io.PrintStream(functionsStream) + (functionsWriter, functionsStream) + })._1)(f) + //ongoingFun -= streamId + } else { + // If a function is registered, don't re-register it. + // withStream(functionsStreams(id)._1)(f) + } + + override def emitAll(g: Graph, name: String)(m1: Manifest[_], m2: Manifest[_]): Unit = { + val ng = init(g) + emitHeaders(stream) + emitln(""" + |/***************************************** + |Emitting Generated Code + |*******************************************/ + """.stripMargin) + val src = run(name, ng) + emitFunctionDecls(stream) + emitDatastructures(stream) + emitFunctions(stream) + emit(src) + emitln(""" + |/***************************************** + |End of Generated Code + |*******************************************/ + |int main(int argc, char *argv[]) { + | Snippet(std::monostate{}); + | return 0; + |}""".stripMargin) + } +} + +trait WasmToCppCompilerDriver[A, B] extends CppSAIDriver[A, B] with StagedWasmEvaluator { q => + override val codegen = new StagedWasmCppGen { + val IR: q.type = q + import IR._ + } +} + +object WasmToCppCompiler { + case class GeneratedCpp(source: String, headerFolders: List[String]) + + def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean = false): GeneratedCpp = { + println(s"Now compiling wasm module with entry function $main") + val driver = new WasmToCppCompilerDriver[Unit, Unit] { + def module: ModuleInstance = moduleInst + def snippet(x: Rep[Unit]): Rep[Unit] = { + evalTop(main, printRes) + } + } + GeneratedCpp(driver.code, driver.codegen.includePaths.toList) + } + + def compileToExe(moduleInst: ModuleInstance, + main: Option[String], + outputCpp: String, + outputExe: String, + printRes: Boolean = false): Unit = { + val generated = compile(moduleInst, main, printRes) + val code = generated.source + + val writer = new java.io.PrintWriter(new java.io.File(outputCpp)) + try { + writer.write(code) + } finally { + writer.close() + } + + import sys.process._ + val command = s"g++ -std=c++17 $outputCpp -o $outputExe -O3 -g " + generated.headerFolders.map(f => s"-I$f").mkString(" ") + if (command.! != 0) { + throw new RuntimeException(s"Compilation failed for $outputCpp") + } + } + +} + From 27e3e32f9269303d21d65583f6b2d14a74b04dbe Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 7 Jul 2025 14:34:24 +0800 Subject: [PATCH 03/82] dup all concrete operations to symbolic --- .../scala/wasm/StagedConcolicMiniWasm.scala | 444 +++++------------- 1 file changed, 111 insertions(+), 333 deletions(-) diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 6b14bcf6..22b593a9 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -13,8 +13,9 @@ import lms.core.Graph import gensym.wasm.ast._ import gensym.wasm.ast.{Const => WasmConst, Block => WasmBlock} import gensym.wasm.miniwasm.{ModuleInstance} -import gensym.wasm.ast.{Const => WasmConst, Block => WasmBlock} +import gensym.wasm.symbolic.{SymVal} import gensym.lmsx.{SAIDriver, StringOps, SAIOps, SAICodeGenBase, CppSAIDriver, CppSAICodeGenBase} +import gensym.wasm.symbolic.Concrete @virtualize trait StagedWasmEvaluator extends SAIOps { @@ -24,25 +25,27 @@ trait StagedWasmEvaluator extends SAIOps { trait StagedNum { def tipe: ValueType = this match { - case I32(_) => NumType(I32Type) - case I64(_) => NumType(I64Type) - case F32(_) => NumType(F32Type) - case F64(_) => NumType(F64Type) + case I32(_, _) => NumType(I32Type) + case I64(_, _) => NumType(I64Type) + case F32(_, _) => NumType(F32Type) + case F64(_, _) => NumType(F64Type) } def i: Rep[Num] + + def s: Rep[SymVal] } - case class I32(i: Rep[Num]) extends StagedNum - case class I64(i: Rep[Num]) extends StagedNum - case class F32(i: Rep[Num]) extends StagedNum - case class F64(i: Rep[Num]) extends StagedNum + case class I32(i: Rep[Num], s: Rep[SymVal]) extends StagedNum + case class I64(i: Rep[Num], s: Rep[SymVal]) extends StagedNum + case class F32(i: Rep[Num], s: Rep[SymVal]) extends StagedNum + case class F64(i: Rep[Num], s: Rep[SymVal]) extends StagedNum implicit def toStagedNum(num: Num): StagedNum = { num match { - case I32V(_) => I32(num) - case I64V(_) => I64(num) - case F32V(_) => F32(num) - case F64V(_) => F64(num) + case I32V(_) => I32(num, Concrete(num)) + case I64V(_) => I64(num, Concrete(num)) + case F32V(_) => F32(num, Concrete(num)) + case F64V(_) => F64(num, Concrete(num)) } } @@ -147,7 +150,7 @@ trait StagedWasmEvaluator extends SAIOps { case Load(LoadOp(align, offset, ty, None, None)) => val (addr, newCtx1) = Stack.pop() val value = Memory.loadInt(addr.toInt, offset) - val newCtx2 = Stack.push(Values.I32V(value))(newCtx1) + val newCtx2 = Stack.push(value)(newCtx1) eval(rest, kont, mkont, trail)(newCtx2) case MemorySize => ??? case MemoryGrow => @@ -414,10 +417,10 @@ trait StagedWasmEvaluator extends SAIOps { def pop()(implicit ctx: Context): (StagedNum, Context) = { val (ty, newContext) = ctx.pop() val num = ty match { - case NumType(I32Type) => I32("stack-pop".reflectCtrlWith[Num]()) - case NumType(I64Type) => I64("stack-pop".reflectCtrlWith[Num]()) - case NumType(F32Type) => F32("stack-pop".reflectCtrlWith[Num]()) - case NumType(F32Type) => F64("stack-pop".reflectCtrlWith[Num]()) + case NumType(I32Type) => I32("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(I64Type) => I64("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F32("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F64("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) } (num, newContext) } @@ -425,22 +428,22 @@ trait StagedWasmEvaluator extends SAIOps { def peek(implicit ctx: Context): (StagedNum, Context) = { val ty = ctx.stackTypes.head val num = ty match { - case NumType(I32Type) => I32("stack-peek".reflectCtrlWith[Num]()) - case NumType(I64Type) => I64("stack-peek".reflectCtrlWith[Num]()) - case NumType(F32Type) => F32("stack-peek".reflectCtrlWith[Num]()) - case NumType(F32Type) => F64("stack-peek".reflectCtrlWith[Num]()) + case NumType(I32Type) => I32("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(I64Type) => I64("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F32("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F64("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) } (num, ctx) } - def push(v: StagedNum)(implicit ctx: Context): Context = { - v match { - case I32(v) => "stack-push".reflectCtrlWith[Unit](v) - case I64(v) => "stack-push".reflectCtrlWith[Unit](v) - case F32(v) => "stack-push".reflectCtrlWith[Unit](v) - case F64(v) => "stack-push".reflectCtrlWith[Unit](v) + def push(num: StagedNum)(implicit ctx: Context): Context = { + num match { + case I32(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) + case I64(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) + case F32(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) + case F64(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) } - ctx.push(v.tipe) + ctx.push(num.tipe) } def take(n: Int)(implicit ctx: Context): (List[StagedNum], Context) = n match { @@ -458,6 +461,7 @@ trait StagedWasmEvaluator extends SAIOps { def shift(offset: Rep[Int], size: Rep[Int]): Rep[Unit] = { if (offset > 0) { "stack-shift".reflectCtrlWith[Unit](offset, size) + "sym-stack-shift".reflectCtrlWith[Unit](offset, size) } } @@ -474,20 +478,20 @@ trait StagedWasmEvaluator extends SAIOps { def get(i: Int)(implicit ctx: Context): StagedNum = { // val offset = ctx.frameTypes.take(i).map(_.size).sum ctx.frameTypes(i) match { - case NumType(I32Type) => I32("frame-get".reflectCtrlWith[Num](i)) - case NumType(I64Type) => I64("frame-get".reflectCtrlWith[Num](i)) - case NumType(F32Type) => F32("frame-get".reflectCtrlWith[Num](i)) - case NumType(F64Type) => F64("frame-get".reflectCtrlWith[Num](i)) + case NumType(I32Type) => I32("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(I64Type) => I64("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(F32Type) => F32("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(F64Type) => F64("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) } } def set(i: Int, v: StagedNum)(implicit ctx: Context): Rep[Unit] = { // val offset = ctx.frameTypes.take(i).map(_.size).sum v match { - case I32(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case I64(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case F32(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case F64(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case I32(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) + case I64(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) + case F32(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) + case F64(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) } } @@ -495,10 +499,12 @@ trait StagedWasmEvaluator extends SAIOps { // Predef.println(s"[DEBUG] push frame: $locals") val size = locals.size "frame-push".reflectCtrlWith[Unit](size) + "sym-frame-push".reflectCtrlWith[Unit](size) } def popFrame(size: Int): Rep[Unit] = { "frame-pop".reflectCtrlWith[Unit](size) + "sym-frame-pop".reflectCtrlWith[Unit](size) } def putAll(args: List[StagedNum])(implicit ctx: Context): Rep[Unit] = { @@ -513,8 +519,8 @@ trait StagedWasmEvaluator extends SAIOps { "memory-store-int".reflectCtrlWith[Unit](base, offset, value) } - def loadInt(base: Rep[Int], offset: Int): Rep[Int] = { - "memory-load-int".reflectCtrlWith[Int](base, offset) + def loadInt(base: Rep[Int], offset: Int): StagedNum = { + I32("I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset)), "sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) } def grow(delta: Rep[Int]): Rep[Int] = { @@ -534,11 +540,11 @@ trait StagedWasmEvaluator extends SAIOps { // runtime values object Values { def I32V(i: Rep[Int]): StagedNum = { - I32("I32V".reflectCtrlWith[Num](i)) + I32("I32V".reflectCtrlWith[Num](i), "Concrete".reflectCtrlWith[SymVal]("I32V".reflectCtrlWith[Num](i))) } def I64V(i: Rep[Long]): StagedNum = { - I64("I64V".reflectCtrlWith[Num](i)) + I64("I64V".reflectCtrlWith[Num](i), "Concrete".reflectCtrlWith[SymVal]("I64V".reflectCtrlWith[Num](i))) } } @@ -546,19 +552,19 @@ trait StagedWasmEvaluator extends SAIOps { object Globals { def apply(i: Int): StagedNum = { module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => I32("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(I64Type), _) => I64("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(F32Type), _) => F32("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(F64Type), _) => F64("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(I32Type), _) => I32("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(I64Type), _) => I64("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(F32Type), _) => F32("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(F64Type), _) => F64("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) } } def update(i: Int, v: StagedNum): Rep[Unit] = { module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i) - case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i) - case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i) - case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i) + case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) + case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) + case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) + case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) } } } @@ -569,382 +575,153 @@ trait StagedWasmEvaluator extends SAIOps { def toInt: Rep[Int] = "num-to-int".reflectCtrlWith[Int](num.i) def clz(): StagedNum = num match { - case I32(i) => I32("clz".reflectCtrlWith[Num](i)) - case I64(i) => I64("clz".reflectCtrlWith[Num](i)) + case I32(x_c, x_s) => I32("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) + case I64(x_c, x_s) => I64("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) } def ctz(): StagedNum = num match { - case I32(i) => I32("ctz".reflectCtrlWith[Num](i)) - case I64(i) => I64("ctz".reflectCtrlWith[Num](i)) + case I32(x_c, x_s) => I32("ctz".reflectCtrlWith[Num](x_c), "sym-ctz".reflectCtrlWith[SymVal](x_s)) + case I64(x_c, x_s) => I64("ctz".reflectCtrlWith[Num](x_c), "sym-ctz".reflectCtrlWith[SymVal](x_s)) } def popcnt(): StagedNum = num match { - case I32(i) => I32("popcnt".reflectCtrlWith[Num](i)) - case I64(i) => I64("popcnt".reflectCtrlWith[Num](i)) + case I32(x_c, x_s) => I32("popcnt".reflectCtrlWith[Num](x_c), "sym-popcnt".reflectCtrlWith[SymVal](x_s)) + case I64(x_c, x_s) => I64("popcnt".reflectCtrlWith[Num](x_c), "sym-popcnt".reflectCtrlWith[SymVal](x_s)) } def +(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-add".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-add".reflectCtrlWith[Num](x, y)) - case (F32(x), F32(y)) => F32("binary-add".reflectCtrlWith[Num](x, y)) - case (F64(x), F64(y)) => F64("binary-add".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) } } + def -(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-sub".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-sub".reflectCtrlWith[Num](x, y)) - case (F32(x), F32(y)) => F32("binary-sub".reflectCtrlWith[Num](x, y)) - case (F64(x), F64(y)) => F64("binary-sub".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) } } def *(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-mul".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-mul".reflectCtrlWith[Num](x, y)) - case (F32(x), F32(y)) => F32("binary-mul".reflectCtrlWith[Num](x, y)) - case (F64(x), F64(y)) => F64("binary-mul".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) } } def /(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-div".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-div".reflectCtrlWith[Num](x, y)) - case (F32(x), F32(y)) => F32("binary-div".reflectCtrlWith[Num](x, y)) - case (F64(x), F64(y)) => F64("binary-div".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) } } def <<(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-shl".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-shl".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) } } def >>(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-shr".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-shr".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) } } def &(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("binary-and".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I64("binary-and".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) + case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) + case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) } } def numEq(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-eq".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-eq".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-eq".reflectCtrlWith[Num](x_c, y_c), "sym-relation-eq".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-eq".reflectCtrlWith[Num](x_c, y_c), "sym-relation-eq".reflectCtrlWith[SymVal](x_s, y_s)) } } def numNe(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-ne".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-ne".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ne".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ne".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ne".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ne".reflectCtrlWith[SymVal](x_s, y_s)) } } def <(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-lt".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-lt".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-lt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-lt".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-lt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-lt".reflectCtrlWith[SymVal](x_s, y_s)) } } def ltu(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-ltu".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-ltu".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ltu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ltu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ltu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ltu".reflectCtrlWith[SymVal](x_s, y_s)) } } def >(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-gt".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-gt".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-gt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gt".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-gt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gt".reflectCtrlWith[SymVal](x_s, y_s)) } } def gtu(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-gtu".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-gtu".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-gtu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gtu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-gtu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gtu".reflectCtrlWith[SymVal](x_s, y_s)) } } def <=(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-le".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-le".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-le".reflectCtrlWith[Num](x_c, y_c), "sym-relation-le".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-le".reflectCtrlWith[Num](x_c, y_c), "sym-relation-le".reflectCtrlWith[SymVal](x_s, y_s)) } } def leu(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-leu".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-leu".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-leu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-leu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-leu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-leu".reflectCtrlWith[SymVal](x_s, y_s)) } } def >=(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-ge".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-ge".reflectCtrlWith[Num](x, y)) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ge".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ge".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ge".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ge".reflectCtrlWith[SymVal](x_s, y_s)) } } def geu(rhs: StagedNum): StagedNum = { (num, rhs) match { - case (I32(x), I32(y)) => I32("relation-geu".reflectCtrlWith[Num](x, y)) - case (I64(x), I64(y)) => I32("relation-geu".reflectCtrlWith[Num](x, y)) - } - } - } -} - -trait StagedWasmScalaGen extends ScalaGenBase with SAICodeGenBase { - override def mayInline(n: Node): Boolean = n match { - case Node(s, "stack-pop", _, _) => false - case _ => super.mayInline(n) - } - - override def traverse(n: Node): Unit = n match { - case Node(_, "stack-drop", List(n), _) => - emit("Stack.drop("); shallow(n); emit(")\n") - case Node(_, "stack-reset", List(n), _) => - emit("Stack.reset("); shallow(n); emit(")\n") - case Node(_, "stack-init", _, _) => - emit("Stack.initialize()\n") - case Node(_, "stack-print", _, _) => - emit("Stack.print()\n") - case Node(_, "frame-push", List(i), _) => - emit("Frames.pushFrame("); shallow(i); emit(")\n") - case Node(_, "frame-pop", List(i), _) => - emit("Frames.popFrame("); shallow(i); emit(")\n") - case Node(_, "frame-putAll", List(args), _) => - emit("Frames.putAll("); shallow(args); emit(")\n") - case Node(_, "frame-set", List(i, value), _) => - emit("Frames.set("); shallow(i); emit(", "); shallow(value); emit(")\n") - case Node(_, "global-set", List(i, value), _) => - emit("Global.globalSet("); shallow(i); emit(", "); shallow(value); emit(")\n") - case _ => super.traverse(n) - } - - // code generation for pure nodes - override def shallow(n: Node): Unit = n match { - case Node(_, "frame-get", List(i), _) => - emit("Frames.get("); shallow(i); emit(")") - case Node(_, "frame-pop", List(i), _) => - emit("Frames.popFrame("); shallow(i); emit(")") - case Node(_, "stack-push", List(value), _) => - emit("Stack.push("); shallow(value); emit(")") - case Node(_, "stack-pop", _, _) => - emit("Stack.pop()") - case Node(_, "stack-peek", _, _) => - emit("Stack.peek") - case Node(_, "stack-take", List(n), _) => - emit("Stack.take("); shallow(n); emit(")") - case Node(_, "stack-size", _, _) => - emit("Stack.size") - case Node(_, "global-get", List(i), _) => - emit("Global.globalGet("); shallow(i); emit(")") - case Node(_, "binary-add", List(lhs, rhs), _) => - shallow(lhs); emit(" + "); shallow(rhs) - case Node(_, "binary-sub", List(lhs, rhs), _) => - shallow(lhs); emit(" - "); shallow(rhs) - case Node(_, "binary-mul", List(lhs, rhs), _) => - shallow(lhs); emit(" * "); shallow(rhs) - case Node(_, "binary-div", List(lhs, rhs), _) => - shallow(lhs); emit(" / "); shallow(rhs) - case Node(_, "binary-shl", List(lhs, rhs), _) => - shallow(lhs); emit(" << "); shallow(rhs) - case Node(_, "binary-shr", List(lhs, rhs), _) => - shallow(lhs); emit(" >> "); shallow(rhs) - case Node(_, "binary-and", List(lhs, rhs), _) => - shallow(lhs); emit(" & "); shallow(rhs) - case Node(_, "relation-eq", List(lhs, rhs), _) => - shallow(lhs); emit(" == "); shallow(rhs) - case Node(_, "relation-ne", List(lhs, rhs), _) => - shallow(lhs); emit(" != "); shallow(rhs) - case Node(_, "relation-lt", List(lhs, rhs), _) => - shallow(lhs); emit(" < "); shallow(rhs) - case Node(_, "relation-ltu", List(lhs, rhs), _) => - shallow(lhs); emit(" < "); shallow(rhs) - case Node(_, "relation-gt", List(lhs, rhs), _) => - shallow(lhs); emit(" > "); shallow(rhs) - case Node(_, "relation-gtu", List(lhs, rhs), _) => - shallow(lhs); emit(" > "); shallow(rhs) - case Node(_, "relation-le", List(lhs, rhs), _) => - shallow(lhs); emit(" <= "); shallow(rhs) - case Node(_, "relation-leu", List(lhs, rhs), _) => - shallow(lhs); emit(" <= "); shallow(rhs) - case Node(_, "relation-ge", List(lhs, rhs), _) => - shallow(lhs); emit(" >= "); shallow(rhs) - case Node(_, "relation-geu", List(lhs, rhs), _) => - shallow(lhs); emit(" >= "); shallow(rhs) - case Node(_, "num-to-int", List(num), _) => - shallow(num); emit(".toInt") - case Node(_, "no-op", _, _) => - emit("()") - case _ => super.shallow(n) - } -} - -trait WasmToScalaCompilerDriver[A, B] - extends SAIDriver[A, B] with StagedWasmEvaluator { q => - override val codegen = new StagedWasmScalaGen { - val IR: q.type = q - import IR._ - override def remap(m: Manifest[_]): String = { - if (m.toString.endsWith("Stack")) "Stack" - else if(m.toString.endsWith("Frame")) "Frame" - else super.remap(m) - } - } - - override val prelude = - """ -object Prelude { - sealed abstract class Num { - def +(that: Num): Num = (this, that) match { - case (I32V(x), I32V(y)) => I32V(x + y) - case (I64V(x), I64V(y)) => I64V(x + y) - case _ => throw new RuntimeException("Invalid addition") - } - - def -(that: Num): Num = (this, that) match { - case (I32V(x), I32V(y)) => I32V(x - y) - case (I64V(x), I64V(y)) => I64V(x - y) - case _ => throw new RuntimeException("Invalid subtraction") - } - - def !=(that: Num): Num = (this, that) match { - case (I32V(x), I32V(y)) => I32V(if (x != y) 1 else 0) - case (I64V(x), I64V(y)) => I32V(if (x != y) 1 else 0) - case _ => throw new RuntimeException("Invalid inequality") - } - - def toInt: Int = this match { - case I32V(i) => i - case I64V(i) => i.toInt - } - } - case class I32V(i: Int) extends Num - case class I64V(i: Long) extends Num - -object Stack { - private val buffer = new scala.collection.mutable.ArrayBuffer[Num]() - def push(v: Num): Unit = buffer.append(v) - def pop(): Num = { - buffer.remove(buffer.size - 1) - } - def peek: Num = { - buffer.last - } - def size: Int = buffer.size - def drop(n: Int): Unit = { - buffer.remove(buffer.size - n, n) - } - def take(n: Int): List[Num] = { - val xs = buffer.takeRight(n).toList - drop(n) - xs - } - def reset(size: Int): Unit = { - info(s"Reset stack to size $size") - while (buffer.size > size) { - buffer.remove(buffer.size - 1) - } - } - def initialize(): Unit = buffer.clear() - def print(): Unit = { - println("Stack: " + buffer.mkString(", ")) - } -} - - class Frame(val size: Int) { - private val data = new Array[Num](size) - def apply(i: Int): Num = { - info(s"frame(${i}) is ${data(i)}") - data(i) - } - def update(i: Int, v: Num): Unit = { - info(s"set frame(${i}) to ${v}") - data(i) = v - } - def putAll(xs: List[Num]): Unit = { - for (i <- 0 until xs.size) { - data(i) = xs(i) + case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-geu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-geu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-geu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-geu".reflectCtrlWith[SymVal](x_s, y_s)) } } - override def toString: String = { - "Frame(" + data.mkString(", ") + ")" - } - } - - object Frames { - private var frames = List[Frame]() - def pushFrame(size: Int): Unit = { - frames = new Frame(size) :: frames - } - def popFrame(): Unit = { - frames = frames.tail - } - def top: Frame = frames.head - def set(i: Int, v: Num): Unit = { - top(i) = v - } - def get(i: Int): Num = { - top(i) - } - } - - object Global { - // TODO: create global with specific size - private val globals = new Array[Num](10) - def globalGet(i: Int): Num = globals(i) - def globalSet(i: Int, v: Num): Unit = globals(i) = v - } - - def info(xs: Any*): Unit = { - if (System.getenv("DEBUG") != null) { - println("[INFO] " + xs.mkString(" ")) - } - } -} -import Prelude._ - - -object Main { - def main(args: Array[String]): Unit = { - val snippet = new Snippet() - snippet(()) - } -} -""" -} - - -object WasmToScalaCompiler { - def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean = false): String = { - println(s"Now compiling wasm module with entry function $main") - val code = new WasmToScalaCompilerDriver[Unit, Unit] { - def module: ModuleInstance = moduleInst - def snippet(x: Rep[Unit]): Rep[Unit] = { - evalTop(main, printRes) - } - } - code.code } } @@ -1168,3 +945,4 @@ object WasmToCppCompiler { } + From 2143050a320d3fa182aa361bc6b9c154aff9045d Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 7 Jul 2025 21:46:15 +0800 Subject: [PATCH 04/82] maintain a symbolic stack during the execution --- headers/wasm.hpp | 1 + headers/wasm/concrete_rt.hpp | 7 +- headers/wasm/symbolic_rt.hpp | 72 +++++++++++++++++++ .../scala/wasm/StagedConcolicMiniWasm.scala | 52 ++++++++++---- .../genwasym/TestStagedConcolicEval.scala | 33 +++++++++ 5 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 headers/wasm/symbolic_rt.hpp create mode 100644 src/test/scala/genwasym/TestStagedConcolicEval.scala diff --git a/headers/wasm.hpp b/headers/wasm.hpp index 21da2ff7..c7e98b6e 100644 --- a/headers/wasm.hpp +++ b/headers/wasm.hpp @@ -2,5 +2,6 @@ #define WASM_HEADERS #include "wasm/concrete_rt.hpp" +#include "wasm/symbolic_rt.hpp" #endif \ No newline at end of file diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 34d739f4..e994cbde 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -1,3 +1,6 @@ +#ifndef WASM_CONCRETE_RT_HPP +#define WASM_CONCRETE_RT_HPP + #include #include #include @@ -200,4 +203,6 @@ struct Memory_t { } }; -static Memory_t Memory(1); // 1 page memory \ No newline at end of file +static Memory_t Memory(1); // 1 page memory + +#endif // WASM_CONCRETE_RT_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp new file mode 100644 index 00000000..d03509ac --- /dev/null +++ b/headers/wasm/symbolic_rt.hpp @@ -0,0 +1,72 @@ +#ifndef WASM_SYMBOLIC_RT_HPP +#define WASM_SYMBOLIC_RT_HPP + +#include "concrete_rt.hpp" +#include + +class SymVal { +public: + SymVal operator+(const SymVal &other) const { + // Define how to add two symbolic values + // Not implemented yet + return SymVal(); + } + + SymVal is_zero() const { + // Check if the symbolic value is zero + // Not implemented yet + return SymVal(); + } +}; + +class SymStack_t { +public: + void push(SymVal val) { + // Push a symbolic value to the stack + // Not implemented yet + } + + SymVal pop() { + // Pop a symbolic value from the stack + // Not implemented yet + return SymVal(); + } + + SymVal peek() { return SymVal(); } +}; + +static SymStack_t SymStack; + +class SymFrames_t { +public: + void pushFrame(int size) { + // Push a new frame with the given size + // Not implemented yet + } + std::monostate popFrame(int size) { + // Pop the frame of the given size + // Not implemented yet + return std::monostate(); + } + + SymVal get(int index) { + // Get the symbolic value at the given index + // Not implemented yet + return SymVal(); + } + + void set(int index, SymVal val) { + // Set the symbolic value at the given index + // Not implemented yet + } +}; + +static SymFrames_t SymFrames; + +static SymVal Concrete(Num num) { + // Convert a concrete number to a symbolic value + // Not implemented yet + return SymVal(); +} + +#endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 22b593a9..c41c7c42 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -40,7 +40,7 @@ trait StagedWasmEvaluator extends SAIOps { case class F32(i: Rep[Num], s: Rep[SymVal]) extends StagedNum case class F64(i: Rep[Num], s: Rep[SymVal]) extends StagedNum - implicit def toStagedNum(num: Num): StagedNum = { + def toStagedNum(num: Num): StagedNum = { num match { case I32V(_) => I32(num, Concrete(num)) case I64V(_) => I64(num, Concrete(num)) @@ -118,7 +118,7 @@ trait StagedWasmEvaluator extends SAIOps { val (_, newCtx) = Stack.pop() eval(rest, kont, mkont, trail)(newCtx) case WasmConst(num) => - val newCtx = Stack.push(num) + val newCtx = Stack.push(toStagedNum(num)) eval(rest, kont, mkont, trail)(newCtx) case LocalGet(i) => val newCtx = Stack.push(Frames.get(i)) @@ -155,7 +155,10 @@ trait StagedWasmEvaluator extends SAIOps { case MemorySize => ??? case MemoryGrow => val (delta, newCtx1) = Stack.pop() - val newCtx2 = Stack.push(Values.I32V(Memory.grow(delta.toInt)))(newCtx1) + val ret = Memory.grow(delta.toInt) + val retNum = Values.I32V(ret) + val retSym = "Concrete".reflectCtrlWith[SymVal](retNum) + val newCtx2 = Stack.push(I32(retNum, retSym))(newCtx1) eval(rest, kont, mkont, trail)(newCtx2) case MemoryFill => ??? case Unreachable => unreachable() @@ -220,6 +223,7 @@ trait StagedWasmEvaluator extends SAIOps { val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) eval(rest, kont, mk, trail)(newRestCtx) }) + // TODO: put the cond.s to path condition if (cond.toInt != 0) { eval(thn, restK _, mkont, restK _ :: trail)(newCtx) } else { @@ -232,6 +236,7 @@ trait StagedWasmEvaluator extends SAIOps { case BrIf(label) => val (cond, newCtx) = Stack.pop() info(s"The br_if(${label})'s condition is ", cond.toInt) + // TODO: put the cond.s to path condition if (cond.toInt != 0) { info(s"Jump to $label") trail(label)(newCtx)(mkont) @@ -320,7 +325,7 @@ trait StagedWasmEvaluator extends SAIOps { } def evalTestOp(op: TestOp, value: StagedNum): StagedNum = op match { - case Eqz(_) => Values.I32V(if (value.toInt == 0) 1 else 0) + case Eqz(_) => value.isZero } def evalUnaryOp(op: UnaryOp, value: StagedNum): StagedNum = op match { @@ -523,6 +528,7 @@ trait StagedWasmEvaluator extends SAIOps { I32("I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset)), "sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) } + // Returns the previous memory size on success, or -1 if the memory cannot be grown. def grow(delta: Rep[Int]): Rep[Int] = { "memory-grow".reflectCtrlWith[Int](delta) } @@ -539,12 +545,12 @@ trait StagedWasmEvaluator extends SAIOps { // runtime values object Values { - def I32V(i: Rep[Int]): StagedNum = { - I32("I32V".reflectCtrlWith[Num](i), "Concrete".reflectCtrlWith[SymVal]("I32V".reflectCtrlWith[Num](i))) + def I32V(i: Rep[Int]): Rep[Num] = { + "I32V".reflectCtrlWith[Num](i) } - def I64V(i: Rep[Long]): StagedNum = { - I64("I64V".reflectCtrlWith[Num](i), "Concrete".reflectCtrlWith[SymVal]("I64V".reflectCtrlWith[Num](i))) + def I64V(i: Rep[Long]): Rep[Num] = { + "I64V".reflectCtrlWith[Num](i) } } @@ -574,6 +580,10 @@ trait StagedWasmEvaluator extends SAIOps { def toInt: Rep[Int] = "num-to-int".reflectCtrlWith[Int](num.i) + def isZero(): StagedNum = num match { + case I32(x_c, x_s) => I32(Values.I32V("is-zero".reflectCtrlWith[Int](num.toInt)), "sym-is-zero".reflectCtrlWith[SymVal](x_s)) + } + def clz(): StagedNum = num match { case I32(x_c, x_s) => I32("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) case I64(x_c, x_s) => I64("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) @@ -750,13 +760,16 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { else if (m.toString.endsWith("Global")) "Global" else if (m.toString.endsWith("I32V")) "I32V" else if (m.toString.endsWith("I64V")) "I64V" + else if (m.toString.endsWith("SymVal")) "SymVal" + else super.remap(m) } - // for now, the traverse/shallow is same as the scala backend's override def traverse(n: Node): Unit = n match { case Node(_, "stack-push", List(value), _) => emit("Stack.push("); shallow(value); emit(");\n") + case Node(_, "sym-stack-push", List(s_value), _) => + emit("SymStack.push("); shallow(s_value); emit(");\n") case Node(_, "stack-drop", List(n), _) => emit("Stack.drop("); shallow(n); emit(");\n") case Node(_, "stack-init", _, _) => @@ -765,12 +778,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.print();\n") case Node(_, "frame-push", List(i), _) => emit("Frames.pushFrame("); shallow(i); emit(");\n") + case Node(_, "sym-frame-push", List(i), _) => + emit("SymFrames.pushFrame("); shallow(i); emit(");\n") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(");\n") - case Node(_, "frame-putAll", List(args), _) => - emit("Frames.putAll("); shallow(args); emit(");\n") case Node(_, "frame-set", List(i, value), _) => emit("Frames.set("); shallow(i); emit(", "); shallow(value); emit(");\n") + case Node(_, "sym-frame-set", List(i, s_value), _) => + emit("SymFrames.set("); shallow(i); emit(", "); shallow(s_value); emit(");\n") case Node(_, "global-set", List(i, value), _) => emit("Global.globalSet("); shallow(i); emit(", "); shallow(value); emit(");\n") // Note: The following code is copied from the traverse of CppBackend.scala, try to avoid duplicated code @@ -787,10 +802,11 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case _ => super.traverse(n) } - // code generation for pure nodes override def shallow(n: Node): Unit = n match { case Node(_, "frame-get", List(i), _) => emit("Frames.get("); shallow(i); emit(")") + case Node(_, "sym-frame-get", List(i), _) => + emit("SymFrames.get("); shallow(i); emit(")") case Node(_, "stack-drop", List(n), _) => emit("Stack.drop("); shallow(n); emit(")") case Node(_, "stack-push", List(value), _) => @@ -799,10 +815,16 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.shift("); shallow(offset); emit(", "); shallow(size); emit(")") case Node(_, "stack-pop", _, _) => emit("Stack.pop()") + case Node(_, "sym-stack-pop", _, _) => + emit("SymStack.pop()") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(")") + case Node(_, "sym-frame-pop", List(i), _) => + emit("SymFrames.popFrame("); shallow(i); emit(")") case Node(_, "stack-peek", _, _) => emit("Stack.peek()") + case Node(_, "sym-stack-peek", _, _) => + emit("SymStack.peek()") case Node(_, "stack-take", List(n), _) => emit("Stack.take("); shallow(n); emit(")") case Node(_, "slice-reverse", List(slice), _) => @@ -817,8 +839,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.size()") case Node(_, "global-get", List(i), _) => emit("Global.globalGet("); shallow(i); emit(")") + case Node(_, "is-zero", List(num), _) => + emit("(0 == "); shallow(num); emit(")") + case Node(_, "sym-is-zero", List(s_num), _) => + shallow(s_num); emit(".is_zero()") case Node(_, "binary-add", List(lhs, rhs), _) => shallow(lhs); emit(" + "); shallow(rhs) + case Node(_, "sym-binary-add", List(lhs, rhs), _) => + shallow(lhs); emit(" + "); shallow(rhs) case Node(_, "binary-sub", List(lhs, rhs), _) => shallow(lhs); emit(" - "); shallow(rhs) case Node(_, "binary-mul", List(lhs, rhs), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala new file mode 100644 index 00000000..eef6ab01 --- /dev/null +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -0,0 +1,33 @@ +package gensym.wasm + +import org.scalatest.FunSuite + +import lms.core.stub.Adapter + +import gensym.wasm.miniwasm.{ModuleInstance} +import gensym.wasm.parser._ +import gensym.wasm.stagedconcolicminiwasm._ + +class TestStagedConcolicEval extends FunSuite { + def testFileToCpp(filename: String, main: Option[String] = None, expect: Option[List[Float]]=None) = { + val moduleInst = ModuleInstance(Parser.parseFile(filename)) + val cppFile = s"$filename.cpp" + val exe = s"$cppFile.exe" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true) + + import sys.process._ + val result = s"./$exe".!! + println(result) + + expect.map(vs => { + val stackValues = result + .split("Stack contents: \n")(1) + .split("\n") + .map(_.toFloat) + .toList + assert(vs == stackValues) + }) + } + + test("ack-cpp") { testFileToCpp("./benchmarks/wasm/ack.wat", Some("real_main"), expect=Some(List(7))) } +} From 8d81fbe2e61a1f7e792be3fb5463d7ead9954ea4 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 9 Jul 2025 19:24:24 +0800 Subject: [PATCH 05/82] record path conditions --- headers/wasm/symbolic_rt.hpp | 18 ++++++++++++++++ .../scala/wasm/StagedConcolicMiniWasm.scala | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index d03509ac..05fc41d4 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -17,6 +17,12 @@ class SymVal { // Not implemented yet return SymVal(); } + + SymVal negate() const { + // negate the symbolic condition by creating a new symbolic value + // not implemented yet + return SymVal(); + } }; class SymStack_t { @@ -69,4 +75,16 @@ static SymVal Concrete(Num num) { return SymVal(); } +class ExploreTree_t { +public: + std::monostate fillIfElseNode(SymVal s, bool branch) { + // fill the current node with the branch condition s + // parameter branch is redundant, to hint which branch we've entered + // Not implemented yet + return std::monostate(); + } +}; + +static ExploreTree_t ExploreTree; + #endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index c41c7c42..1eb717e3 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -225,8 +225,10 @@ trait StagedWasmEvaluator extends SAIOps { }) // TODO: put the cond.s to path condition if (cond.toInt != 0) { + ExploreTree.fillWithIfElse(cond.s, true) eval(thn, restK _, mkont, restK _ :: trail)(newCtx) } else { + ExploreTree.fillWithIfElse(cond.s.not, false) eval(els, restK _, mkont, restK _ :: trail)(newCtx) } () @@ -239,9 +241,11 @@ trait StagedWasmEvaluator extends SAIOps { // TODO: put the cond.s to path condition if (cond.toInt != 0) { info(s"Jump to $label") + ExploreTree.fillWithIfElse(cond.s, true) trail(label)(newCtx)(mkont) } else { info(s"Continue") + ExploreTree.fillWithIfElse(cond.s.not, false) eval(rest, kont, mkont, trail)(newCtx) } () @@ -575,6 +579,13 @@ trait StagedWasmEvaluator extends SAIOps { } } + // Exploration tree, + object ExploreTree { + def fillWithIfElse(s: Rep[SymVal], branch: Boolean): Rep[Unit] = { + "tree-fill-if-else".reflectCtrlWith[Unit](s, branch) + } + } + // runtime Num type implicit class StagedNumOps(num: StagedNum) { @@ -733,6 +744,12 @@ trait StagedWasmEvaluator extends SAIOps { } } } + + implicit class SymbolicOps(s: Rep[SymVal]) { + def not(): Rep[SymVal] = { + "sym-not".reflectCtrlWith(s) + } + } } trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { @@ -881,6 +898,10 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(" >= "); shallow(rhs) case Node(_, "num-to-int", List(num), _) => shallow(num); emit(".toInt()") + case Node(_, "tree-fill-if-else", List(s, b), _) => + emit("ExploreTree.fillIfElseNode("); shallow(s); emit(", "); shallow(b); emit(")") + case Node(_, "sym-not", List(s), _) => + shallow(s); emit(".negate()") case Node(_, "dummy", _, _) => emit("std::monostate()") case Node(_, "dummy-op", _, _) => emit("std::monostate()") case Node(_, "no-op", _, _) => From 61215b6c87a2ba1ffa3f88838c17dc3d7e3cfb86 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 9 Jul 2025 23:06:44 +0800 Subject: [PATCH 06/82] The branch node only needs to remember the positive condition. use the sub-nodes of the branch to classify whether the execution is true or false --- headers/wasm/symbolic_rt.hpp | 6 ++++- .../scala/wasm/StagedConcolicMiniWasm.scala | 24 ++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 05fc41d4..a0199db4 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -77,12 +77,16 @@ static SymVal Concrete(Num num) { class ExploreTree_t { public: - std::monostate fillIfElseNode(SymVal s, bool branch) { + std::monostate fillIfElseNode(SymVal s) { // fill the current node with the branch condition s // parameter branch is redundant, to hint which branch we've entered // Not implemented yet return std::monostate(); } + + std::monostate moveCursor(bool branch) { + return std::monostate(); + } }; static ExploreTree_t ExploreTree; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 1eb717e3..d31af3cb 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -224,11 +224,12 @@ trait StagedWasmEvaluator extends SAIOps { eval(rest, kont, mk, trail)(newRestCtx) }) // TODO: put the cond.s to path condition + ExploreTree.fillWithIfElse(cond.s) if (cond.toInt != 0) { - ExploreTree.fillWithIfElse(cond.s, true) + ExploreTree.moveCursor(true) eval(thn, restK _, mkont, restK _ :: trail)(newCtx) } else { - ExploreTree.fillWithIfElse(cond.s.not, false) + ExploreTree.moveCursor(false) eval(els, restK _, mkont, restK _ :: trail)(newCtx) } () @@ -239,13 +240,14 @@ trait StagedWasmEvaluator extends SAIOps { val (cond, newCtx) = Stack.pop() info(s"The br_if(${label})'s condition is ", cond.toInt) // TODO: put the cond.s to path condition + ExploreTree.fillWithIfElse(cond.s) if (cond.toInt != 0) { info(s"Jump to $label") - ExploreTree.fillWithIfElse(cond.s, true) + ExploreTree.moveCursor(true) trail(label)(newCtx)(mkont) } else { info(s"Continue") - ExploreTree.fillWithIfElse(cond.s.not, false) + ExploreTree.moveCursor(false) eval(rest, kont, mkont, trail)(newCtx) } () @@ -581,8 +583,12 @@ trait StagedWasmEvaluator extends SAIOps { // Exploration tree, object ExploreTree { - def fillWithIfElse(s: Rep[SymVal], branch: Boolean): Rep[Unit] = { - "tree-fill-if-else".reflectCtrlWith[Unit](s, branch) + def fillWithIfElse(s: Rep[SymVal]): Rep[Unit] = { + "tree-fill-if-else".reflectCtrlWith[Unit](s) + } + + def moveCursor(branch: Boolean): Rep[Unit] = { + "tree-move-cursor".reflectCtrlWith[Unit](branch) } } @@ -898,8 +904,10 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(" >= "); shallow(rhs) case Node(_, "num-to-int", List(num), _) => shallow(num); emit(".toInt()") - case Node(_, "tree-fill-if-else", List(s, b), _) => - emit("ExploreTree.fillIfElseNode("); shallow(s); emit(", "); shallow(b); emit(")") + case Node(_, "tree-fill-if-else", List(s), _) => + emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") + case Node(_, "tree-move-cursor", List(b), _) => + emit("ExploreTree.moveCursor("); shallow(b); emit(")") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") case Node(_, "dummy", _, _) => emit("std::monostate()") From d18b5f7ca62dc6a96baca04eb38f638d06e41b0b Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 13 Jul 2025 14:57:36 +0800 Subject: [PATCH 07/82] symbolic runtime for explore tree --- headers/wasm/symbolic_rt.hpp | 86 ++++++++++++++++++- .../scala/wasm/StagedConcolicMiniWasm.scala | 8 ++ 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index a0199db4..4373af84 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -2,6 +2,9 @@ #define WASM_SYMBOLIC_RT_HPP #include "concrete_rt.hpp" +#include +#include +#include #include class SymVal { @@ -75,18 +78,93 @@ static SymVal Concrete(Num num) { return SymVal(); } +struct Node; + +struct NodeBox { + explicit NodeBox(); + std::unique_ptr node; + NodeBox *parent; +}; + +struct Node { + virtual ~Node(){}; + virtual std::string to_string() = 0; +}; + +struct IfElseNode : Node { + SymVal cond; + std::unique_ptr true_branch; + std::unique_ptr false_branch; + + IfElseNode(SymVal cond) + : cond(cond), true_branch(std::make_unique()), + false_branch(std::make_unique()) {} + + std::string to_string() override { + std::string result = "IfElseNode {\n"; + result += " true_branch: "; + if (true_branch) { + result += true_branch->node->to_string(); + } else { + result += "nullptr"; + } + result += "\n"; + + result += " false_branch: "; + if (false_branch) { + result += false_branch->node->to_string(); + } else { + result += "nullptr"; + } + result += "\n"; + result += "}"; + return result; + } +}; + +struct UnExploredNode : Node { + UnExploredNode() {} + std::string to_string() override { return "UnexploredNode"; } +}; + +static UnExploredNode unexplored; + +inline NodeBox::NodeBox() + : node(std::make_unique< + UnExploredNode>() /* TODO: avoid allocation of unexplored node */) {} + class ExploreTree_t { public: - std::monostate fillIfElseNode(SymVal s) { - // fill the current node with the branch condition s - // parameter branch is redundant, to hint which branch we've entered - // Not implemented yet + explicit ExploreTree_t() + : root(std::make_unique()), cursor(root.get()) {} + std::monostate fillIfElseNode(SymVal cond) { + // fill the current node with an ifelse branch node + cursor->node = std::make_unique(cond); return std::monostate(); } std::monostate moveCursor(bool branch) { + assert(cursor != nullptr); + auto if_else_node = dynamic_cast(cursor->node.get()); + assert( + if_else_node != nullptr && + "Can't move cursor when the branch node is not initialized correctly!"); + if (branch) { + cursor = if_else_node->true_branch.get(); + } else { + cursor = if_else_node->false_branch.get(); + } return std::monostate(); } + + std::monostate print() { + std::cout << root->node->to_string() << std::endl; + return std::monostate(); + } + +private: + std::unique_ptr root; + NodeBox *cursor; }; static ExploreTree_t ExploreTree; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index d31af3cb..4366ac78 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -16,6 +16,7 @@ import gensym.wasm.miniwasm.{ModuleInstance} import gensym.wasm.symbolic.{SymVal} import gensym.lmsx.{SAIDriver, StringOps, SAIOps, SAICodeGenBase, CppSAIDriver, CppSAICodeGenBase} import gensym.wasm.symbolic.Concrete +import gensym.wasm.symbolic.ExploreTree @virtualize trait StagedWasmEvaluator extends SAIOps { @@ -405,6 +406,7 @@ trait StagedWasmEvaluator extends SAIOps { info("Exiting the program...") if (printRes) { Stack.print() + ExploreTree.print() } "no-op".reflectCtrlWith[Unit]() } @@ -590,6 +592,10 @@ trait StagedWasmEvaluator extends SAIOps { def moveCursor(branch: Boolean): Rep[Unit] = { "tree-move-cursor".reflectCtrlWith[Unit](branch) } + + def print(): Rep[Unit] = { + "tree-print".reflectCtrlWith[Unit]() + } } // runtime Num type @@ -908,6 +914,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") case Node(_, "tree-move-cursor", List(b), _) => emit("ExploreTree.moveCursor("); shallow(b); emit(")") + case Node(_, "tree-print", List(), _) => + emit("ExploreTree.print()") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") case Node(_, "dummy", _, _) => emit("std::monostate()") From 92ab8ba0d03ec8ef8f3dd9a3b43a32d0c1bfc158 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 14 Jul 2025 01:30:20 +0800 Subject: [PATCH 08/82] add a to graphviz method, enhancing debug experience --- headers/wasm/symbolic_rt.hpp | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 4373af84..02c3021c 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -3,8 +3,10 @@ #include "concrete_rt.hpp" #include +#include #include #include +#include #include class SymVal { @@ -89,8 +91,29 @@ struct NodeBox { struct Node { virtual ~Node(){}; virtual std::string to_string() = 0; + void to_graphviz(std::ostream &os) { + os << "digraph G {\n"; + os << " rankdir=TB;\n"; + os << " node [shape=box, style=filled, fillcolor=lightblue];\n"; + current_id = 0; + generate_dot(os, -1, ""); + + os << "}\n"; + } + int get_next_id(int &id_counter) { return id_counter++; } + virtual int generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) = 0; + +protected: + // Counter for unique node IDs across the entire graph, only for generating + // graphviz purpose + static int current_id; }; +// TODO: use this header file in multiple compilation units will cause problems +// during linking +int Node::current_id = 0; + struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; @@ -120,11 +143,56 @@ struct IfElseNode : Node { result += "}"; return result; } + + int generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id; + current_id += 1; + + os << " node" << current_node_dot_id << " [label=\"If\"," + << "shape=diamond, fillcolor=lightyellow];\n"; + + // Draw edge from parent if this is not the root node + if (parent_dot_id != -1) { + os << " node" << parent_dot_id << " -> node" << current_node_dot_id; + if (!edge_label.empty()) { + os << " [label=\"" << edge_label << "\"]"; + } + os << ";\n"; + } + assert(true_branch != nullptr); + assert(true_branch->node != nullptr); + true_branch->node->generate_dot(os, current_node_dot_id, "true"); + assert(false_branch != nullptr); + assert(false_branch->node != nullptr); + false_branch->node->generate_dot(os, current_node_dot_id, "false"); + return current_node_dot_id; + } }; struct UnExploredNode : Node { UnExploredNode() {} std::string to_string() override { return "UnexploredNode"; } + +protected: + int generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + + os << " node" << current_node_dot_id + << " [label=\"Unexplored\", shape=octagon, style=filled, " + "fillcolor=lightgrey];\n"; + + if (parent_dot_id != -1) { + os << " node" << parent_dot_id << " -> node" << current_node_dot_id; + if (!edge_label.empty()) { + os << " [label=\"" << edge_label << "\"]"; + } + os << ";\n"; + } + + return current_node_dot_id; + } }; static UnExploredNode unexplored; @@ -162,6 +230,11 @@ class ExploreTree_t { return std::monostate(); } + std::monostate to_graphviz(std::ostream &os) { + root->node->to_graphviz(os); + return std::monostate(); + } + private: std::unique_ptr root; NodeBox *cursor; From e1d7fc8fe801a877c8ef7e09d904e8714f6bbd17 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 14 Jul 2025 23:49:20 +0800 Subject: [PATCH 09/82] put symbolic expression on the SymStack --- headers/wasm/symbolic_rt.hpp | 126 +++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 34 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 02c3021c..fac3ce6d 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -8,42 +8,104 @@ #include #include #include +#include -class SymVal { +class Symbolic {}; + +class SymConcrete : public Symbolic { public: - SymVal operator+(const SymVal &other) const { - // Define how to add two symbolic values - // Not implemented yet - return SymVal(); - } + Num value; + SymConcrete(Num num) : value(num) {} +}; - SymVal is_zero() const { - // Check if the symbolic value is zero - // Not implemented yet - return SymVal(); - } +struct SymBinary; - SymVal negate() const { - // negate the symbolic condition by creating a new symbolic value - // not implemented yet - return SymVal(); - } +struct SymVal { + std::shared_ptr symptr; + + SymVal() : symptr(nullptr) {} + SymVal(std::shared_ptr symptr) : symptr(symptr) {} + + SymVal add(const SymVal &other) const; + SymVal minus(const SymVal &other) const; + SymVal mul(const SymVal &other) const; + SymVal div(const SymVal &other) const; + SymVal eq(const SymVal &other) const; + SymVal neq(const SymVal &other) const; + SymVal lt(const SymVal &other) const; + SymVal leq(const SymVal &other) const; + SymVal gt(const SymVal &other) const; + SymVal geq(const SymVal &other) const; +}; + +inline SymVal Concrete(Num num) { + return SymVal(std::make_shared(num)); +} + +enum Operation { ADD, SUB, MUL, DIV, EQ, NEQ, LT, LEQ, GT, GEQ }; + +struct SymBinary : Symbolic { + Operation op; + SymVal lhs; + SymVal rhs; + + SymBinary(Operation op, SymVal lhs, SymVal rhs) + : op(op), lhs(lhs), rhs(rhs) {} }; +inline SymVal SymVal::add(const SymVal &other) const { + return SymVal(std::make_shared(ADD, this, other)); +} + +inline SymVal SymVal::minus(const SymVal &other) const { + return SymVal(std::make_shared(SUB, this, other)); +} + +inline SymVal SymVal::mul(const SymVal &other) const { + return SymVal(std::make_shared(MUL, this, other)); +} + +inline SymVal SymVal::div(const SymVal &other) const { + return SymVal(std::make_shared(DIV, this, other)); +} + +inline SymVal SymVal::eq(const SymVal &other) const { + return SymVal(std::make_shared(EQ, this, other)); +} + +inline SymVal SymVal::neq(const SymVal &other) const { + return SymVal(std::make_shared(NEQ, this, other)); +} +inline SymVal SymVal::lt(const SymVal &other) const { + return SymVal(std::make_shared(LT, this, other)); +} +inline SymVal SymVal::leq(const SymVal &other) const { + return SymVal(std::make_shared(LEQ, this, other)); +} +inline SymVal SymVal::gt(const SymVal &other) const { + return SymVal(std::make_shared(GT, this, other)); +} +inline SymVal SymVal::geq(const SymVal &other) const { + return SymVal(std::make_shared(GEQ, this, other)); +} + class SymStack_t { public: void push(SymVal val) { // Push a symbolic value to the stack - // Not implemented yet + stack.push_back(val); } SymVal pop() { // Pop a symbolic value from the stack - // Not implemented yet - return SymVal(); + auto ret = stack.back(); + stack.pop_back(); + return ret; } - SymVal peek() { return SymVal(); } + SymVal peek() { return stack.back(); } + + std::vector stack; }; static SymStack_t SymStack; @@ -52,34 +114,30 @@ class SymFrames_t { public: void pushFrame(int size) { // Push a new frame with the given size - // Not implemented yet + stack.resize(size + stack.size()); } std::monostate popFrame(int size) { // Pop the frame of the given size - // Not implemented yet + stack.resize(stack.size() - size); return std::monostate(); } SymVal get(int index) { - // Get the symbolic value at the given index - // Not implemented yet - return SymVal(); + // Get the symbolic value at the given frame index + return stack[stack.size() - 1 - index]; } void set(int index, SymVal val) { // Set the symbolic value at the given index // Not implemented yet + stack[stack.size() - 1 - index] = val; } + + std::vector stack; }; static SymFrames_t SymFrames; -static SymVal Concrete(Num num) { - // Convert a concrete number to a symbolic value - // Not implemented yet - return SymVal(); -} - struct Node; struct NodeBox { @@ -115,11 +173,11 @@ struct Node { int Node::current_id = 0; struct IfElseNode : Node { - SymVal cond; + Symbolic cond; std::unique_ptr true_branch; std::unique_ptr false_branch; - IfElseNode(SymVal cond) + IfElseNode(Symbolic cond) : cond(cond), true_branch(std::make_unique()), false_branch(std::make_unique()) {} @@ -205,7 +263,7 @@ class ExploreTree_t { public: explicit ExploreTree_t() : root(std::make_unique()), cursor(root.get()) {} - std::monostate fillIfElseNode(SymVal cond) { + std::monostate fillIfElseNode(Symbolic cond) { // fill the current node with an ifelse branch node cursor->node = std::make_unique(cond); return std::monostate(); From 77a4e6f58547a71a5544779f06f41e92b5398375 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 16 Jul 2025 22:50:08 +0800 Subject: [PATCH 10/82] `type.symbolic` instruction --- headers/wasm/symbolic_rt.hpp | 70 +++++++++++++++---- .../scala/wasm/StagedConcolicMiniWasm.scala | 62 +++++++++++++++- .../genwasym/TestStagedConcolicEval.scala | 4 ++ 3 files changed, 120 insertions(+), 16 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index fac3ce6d..e0d3feef 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -10,7 +10,19 @@ #include #include -class Symbolic {}; +class Symbolic { +public: + Symbolic() {} // TODO: remove this default constructor later + virtual ~Symbolic() = default; // Make Symbolic polymorphic +}; + +class Symbol : public Symbolic { +public: + Symbol(int id) : id(id) {} + +private: + int id; +}; class SymConcrete : public Symbolic { public: @@ -26,6 +38,11 @@ struct SymVal { SymVal() : symptr(nullptr) {} SymVal(std::shared_ptr symptr) : symptr(symptr) {} + // data structure operations + SymVal makeSymbolic() const; + + // arithmetic operations + SymVal is_zero() const; SymVal add(const SymVal &other) const; SymVal minus(const SymVal &other) const; SymVal mul(const SymVal &other) const; @@ -54,39 +71,53 @@ struct SymBinary : Symbolic { }; inline SymVal SymVal::add(const SymVal &other) const { - return SymVal(std::make_shared(ADD, this, other)); + return SymVal(std::make_shared(ADD, *this, other)); } inline SymVal SymVal::minus(const SymVal &other) const { - return SymVal(std::make_shared(SUB, this, other)); + return SymVal(std::make_shared(SUB, *this, other)); } inline SymVal SymVal::mul(const SymVal &other) const { - return SymVal(std::make_shared(MUL, this, other)); + return SymVal(std::make_shared(MUL, *this, other)); } inline SymVal SymVal::div(const SymVal &other) const { - return SymVal(std::make_shared(DIV, this, other)); + return SymVal(std::make_shared(DIV, *this, other)); } inline SymVal SymVal::eq(const SymVal &other) const { - return SymVal(std::make_shared(EQ, this, other)); + return SymVal(std::make_shared(EQ, *this, other)); } inline SymVal SymVal::neq(const SymVal &other) const { - return SymVal(std::make_shared(NEQ, this, other)); + return SymVal(std::make_shared(NEQ, *this, other)); } inline SymVal SymVal::lt(const SymVal &other) const { - return SymVal(std::make_shared(LT, this, other)); + return SymVal(std::make_shared(LT, *this, other)); } inline SymVal SymVal::leq(const SymVal &other) const { - return SymVal(std::make_shared(LEQ, this, other)); + return SymVal(std::make_shared(LEQ, *this, other)); } inline SymVal SymVal::gt(const SymVal &other) const { - return SymVal(std::make_shared(GT, this, other)); + return SymVal(std::make_shared(GT, *this, other)); } inline SymVal SymVal::geq(const SymVal &other) const { - return SymVal(std::make_shared(GEQ, this, other)); + return SymVal(std::make_shared(GEQ, *this, other)); +} +inline SymVal SymVal::is_zero() const { + return SymVal(std::make_shared(EQ, *this, Concrete(I32V(0)))); +} + +inline SymVal SymVal::makeSymbolic() const { + auto concrete = dynamic_cast(symptr.get()); + if (concrete) { + // If the symbolic value is a concrete value, use it to create a symbol + return SymVal(std::make_shared(concrete->value.toInt())); + } else { + throw std::runtime_error( + "Cannot make symbolic a non-concrete symbolic value"); + } } class SymStack_t { @@ -173,11 +204,11 @@ struct Node { int Node::current_id = 0; struct IfElseNode : Node { - Symbolic cond; + SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; - IfElseNode(Symbolic cond) + IfElseNode(SymVal cond) : cond(cond), true_branch(std::make_unique()), false_branch(std::make_unique()) {} @@ -263,7 +294,7 @@ class ExploreTree_t { public: explicit ExploreTree_t() : root(std::make_unique()), cursor(root.get()) {} - std::monostate fillIfElseNode(Symbolic cond) { + std::monostate fillIfElseNode(SymVal cond) { // fill the current node with an ifelse branch node cursor->node = std::make_unique(cond); return std::monostate(); @@ -300,4 +331,15 @@ class ExploreTree_t { static ExploreTree_t ExploreTree; +class SymEnv_t { +public: + Num read(SymVal sym) { + // Read a symbolic value from the symbolic environment + // For now, we just return a zero + return Num(0); + } +}; + +static SymEnv_t SymEnv; + #endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 4366ac78..01bb91c2 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -57,6 +57,15 @@ trait StagedWasmEvaluator extends SAIOps { case NumType(F32Type) => 4 case NumType(F64Type) => 8 } + + def toTagger: (Rep[Num], Rep[SymVal]) => StagedNum = { + ty match { + case NumType(I32Type) => I32 + case NumType(I64Type) => I64 + case NumType(F32Type) => F32 + case NumType(F64Type) => F64 + } + } } case class Context( @@ -121,6 +130,14 @@ trait StagedWasmEvaluator extends SAIOps { case WasmConst(num) => val newCtx = Stack.push(toStagedNum(num)) eval(rest, kont, mkont, trail)(newCtx) + case Symbolic(ty) => + val (id, newCtx1) = Stack.pop() + val symVal = id.makeSymbolic() + val concVal = SymEnv.read(symVal) + val tagger = ty.toTagger + val value = tagger(concVal, symVal) + val newCtx2 = Stack.push(value)(newCtx1) + eval(rest, kont, mkont, trail)(newCtx2) case LocalGet(i) => val newCtx = Stack.push(Frames.get(i)) eval(rest, kont, mkont, trail)(newCtx) @@ -326,6 +343,10 @@ trait StagedWasmEvaluator extends SAIOps { val (v, newCtx) = Stack.pop() println(v.toInt) eval(rest, kont, mkont, trail)(newCtx) + case Import("console", "assert", _) => + val (v, newCtx) = Stack.pop() + runtimeAssert(v.toInt != 0) + eval(rest, kont, mkont, trail)(newCtx) case Import(_, _, _) => throw new Exception(s"Unknown import at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") } @@ -414,6 +435,10 @@ trait StagedWasmEvaluator extends SAIOps { evalTop(temp, main) } + def runtimeAssert(b: Rep[Boolean]): Rep[Unit] = { + "assert-true".reflectCtrlWith[Unit](b) + } + // stack operations object Stack { def shift(offset: Int, size: Int)(ctx: Context): Context = { @@ -598,6 +623,12 @@ trait StagedWasmEvaluator extends SAIOps { } } + object SymEnv { + def read(sym: Rep[SymVal]): Rep[Num] = { + "sym-env-read".reflectCtrlWith[Num](sym) + } + } + // runtime Num type implicit class StagedNumOps(num: StagedNum) { @@ -622,6 +653,10 @@ trait StagedWasmEvaluator extends SAIOps { case I64(x_c, x_s) => I64("popcnt".reflectCtrlWith[Num](x_c), "sym-popcnt".reflectCtrlWith[SymVal](x_s)) } + def makeSymbolic(): Rep[SymVal] = { + "make-symbolic".reflectCtrlWith[SymVal](num.s) + } + def +(rhs: StagedNum): StagedNum = { (num, rhs) match { case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) @@ -778,6 +813,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { override def mayInline(n: Node): Boolean = n match { case Node(_, "stack-pop", _, _) | Node(_, "stack-peek", _, _) + | Node(_, "sym-stack-pop", _, _) => false case _ => super.mayInline(n) } @@ -874,8 +910,6 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(s_num); emit(".is_zero()") case Node(_, "binary-add", List(lhs, rhs), _) => shallow(lhs); emit(" + "); shallow(rhs) - case Node(_, "sym-binary-add", List(lhs, rhs), _) => - shallow(lhs); emit(" + "); shallow(rhs) case Node(_, "binary-sub", List(lhs, rhs), _) => shallow(lhs); emit(" - "); shallow(rhs) case Node(_, "binary-mul", List(lhs, rhs), _) => @@ -908,8 +942,32 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(" >= "); shallow(rhs) case Node(_, "relation-geu", List(lhs, rhs), _) => shallow(lhs); emit(" >= "); shallow(rhs) + case Node(_, "sym-binary-add", List(lhs, rhs), _) => + shallow(lhs); emit(".add("); shallow(rhs); emit(")") + case Node(_, "sym-binary-mul", List(lhs, rhs), _) => + shallow(lhs); emit(".mul("); shallow(rhs); emit(")") + case Node(_, "sym-binary-div", List(lhs, rhs), _) => + shallow(lhs); emit(".div("); shallow(rhs); emit(")") + case Node(_, "sym-relation-le", List(lhs, rhs), _) => + shallow(lhs); emit(".leq("); shallow(rhs); emit(")") + case Node(_, "sym-relation-leu", List(lhs, rhs), _) => + shallow(lhs); emit(".leu("); shallow(rhs); emit(")") + case Node(_, "sym-relation-ge", List(lhs, rhs), _) => + shallow(lhs); emit(".ge("); shallow(rhs); emit(")") + case Node(_, "sym-relation-geu", List(lhs, rhs), _) => + shallow(lhs); emit(".geu("); shallow(rhs); emit(")") + case Node(_, "sym-relation-eq", List(lhs, rhs), _) => + shallow(lhs); emit(".eq("); shallow(rhs); emit(")") + case Node(_, "sym-relation-ne", List(lhs, rhs), _) => + shallow(lhs); emit(".neq("); shallow(rhs); emit(")") case Node(_, "num-to-int", List(num), _) => shallow(num); emit(".toInt()") + case Node(_, "make-symbolic", List(num), _) => + shallow(num); emit(".makeSymbolic()") + case Node(_, "sym-env-read", List(sym), _) => + emit("SymEnv.read("); shallow(sym); emit(")") + case Node(_, "assert-true", List(cond), _) => + emit("assert("); shallow(cond); emit(")") case Node(_, "tree-fill-if-else", List(s), _) => emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") case Node(_, "tree-move-cursor", List(b), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index eef6ab01..409bd07a 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -30,4 +30,8 @@ class TestStagedConcolicEval extends FunSuite { } test("ack-cpp") { testFileToCpp("./benchmarks/wasm/ack.wat", Some("real_main"), expect=Some(List(7))) } + + test("bug-finding") { + testFileToCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) + } } From 314ff5fe8b848cb1f40ee774283489c0760eec35 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 16 Jul 2025 23:11:33 +0800 Subject: [PATCH 11/82] test staged concolic compilation in CI --- .github/workflows/scala.yml | 1 + benchmarks/wasm/branch-strip-buggy.wat | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index 4677da77..d2f8348b 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -79,3 +79,4 @@ jobs: sbt 'testOnly gensym.wasm.TestConcolic' sbt 'testOnly gensym.wasm.TestDriver' sbt 'testOnly gensym.wasm.TestStagedEval' + sbt 'testOnly gensym.wasm.TestStagedConcolicEval' diff --git a/benchmarks/wasm/branch-strip-buggy.wat b/benchmarks/wasm/branch-strip-buggy.wat index c957db7f..0685f0be 100644 --- a/benchmarks/wasm/branch-strip-buggy.wat +++ b/benchmarks/wasm/branch-strip-buggy.wat @@ -29,6 +29,7 @@ else i32.const 0 call 2 + i32.const 1 ;; to satisfy the type checker, this line will never be reached end end ) From 873936902fe34538c698fbd664df370b9133003c Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 17 Jul 2025 00:18:51 +0800 Subject: [PATCH 12/82] dump graphviz by default --- headers/wasm/symbolic_rt.hpp | 10 +++++++++ .../scala/wasm/StagedConcolicMiniWasm.scala | 22 ++++++++++++++----- .../genwasym/TestStagedConcolicEval.scala | 3 ++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index e0d3feef..a97fd0dd 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -4,6 +4,7 @@ #include "concrete_rt.hpp" #include #include +#include #include #include #include @@ -324,6 +325,15 @@ class ExploreTree_t { return std::monostate(); } + std::monostate dump_graphviz(std::string filepath) { + std::ofstream ofs(filepath); + if (!ofs.is_open()) { + throw std::runtime_error("Failed to open explore_tree.dot for writing"); + } + to_graphviz(ofs); + return std::monostate(); + } + private: std::unique_ptr root; NodeBox *cursor; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 01bb91c2..3c342177 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -422,12 +422,15 @@ trait StagedWasmEvaluator extends SAIOps { Frames.popFrame(locals.size) } - def evalTop(main: Option[String], printRes: Boolean = false): Rep[Unit] = { + def evalTop(main: Option[String], printRes: Boolean, dumpTree: Option[String]): Rep[Unit] = { val haltK: Rep[Unit] => Rep[Unit] = (_) => { info("Exiting the program...") if (printRes) { Stack.print() - ExploreTree.print() + } + dumpTree match { + case Some(filePath) => ExploreTree.dumpGraphiviz(filePath) + case None => () } "no-op".reflectCtrlWith[Unit]() } @@ -621,6 +624,10 @@ trait StagedWasmEvaluator extends SAIOps { def print(): Rep[Unit] = { "tree-print".reflectCtrlWith[Unit]() } + + def dumpGraphiviz(filePath: String): Rep[Unit] = { + "tree-dump-graphviz".reflectCtrlWith[Unit](filePath) + } } object SymEnv { @@ -974,6 +981,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.moveCursor("); shallow(b); emit(")") case Node(_, "tree-print", List(), _) => emit("ExploreTree.print()") + case Node(_, "tree-dump-graphviz", List(f), _) => + emit("ExploreTree.dump_graphviz("); shallow(f); emit(")") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") case Node(_, "dummy", _, _) => emit("std::monostate()") @@ -1033,12 +1042,12 @@ trait WasmToCppCompilerDriver[A, B] extends CppSAIDriver[A, B] with StagedWasmEv object WasmToCppCompiler { case class GeneratedCpp(source: String, headerFolders: List[String]) - def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean = false): GeneratedCpp = { + def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean, dumpTree: Option[String]): GeneratedCpp = { println(s"Now compiling wasm module with entry function $main") val driver = new WasmToCppCompilerDriver[Unit, Unit] { def module: ModuleInstance = moduleInst def snippet(x: Rep[Unit]): Rep[Unit] = { - evalTop(main, printRes) + evalTop(main, printRes, dumpTree) } } GeneratedCpp(driver.code, driver.codegen.includePaths.toList) @@ -1048,8 +1057,9 @@ object WasmToCppCompiler { main: Option[String], outputCpp: String, outputExe: String, - printRes: Boolean = false): Unit = { - val generated = compile(moduleInst, main, printRes) + printRes: Boolean, + dumpTree: Option[String]): Unit = { + val generated = compile(moduleInst, main, printRes, dumpTree) val code = generated.source val writer = new java.io.PrintWriter(new java.io.File(outputCpp)) diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 409bd07a..77868e2c 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -13,7 +13,8 @@ class TestStagedConcolicEval extends FunSuite { val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" val exe = s"$cppFile.exe" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true) + val exploreTreeFile = s"$filename.tree.dot" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, Some(exploreTreeFile)) import sys.process._ val result = s"./$exe".!! From 9a9988c560f58961b2fb09892912623c26b9691e Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 17 Jul 2025 18:15:48 +0800 Subject: [PATCH 13/82] concolic driver --- headers/wasm.hpp | 3 +- headers/wasm/concolic_driver.hpp | 98 +++++++++ headers/wasm/concrete_rt.hpp | 9 +- headers/wasm/smt_solver.hpp | 28 +++ headers/wasm/symbolic_rt.hpp | 205 +++++++++++++++--- headers/wasm/utils.hpp | 15 ++ .../scala/wasm/StagedConcolicMiniWasm.scala | 20 +- 7 files changed, 338 insertions(+), 40 deletions(-) create mode 100644 headers/wasm/concolic_driver.hpp create mode 100644 headers/wasm/smt_solver.hpp create mode 100644 headers/wasm/utils.hpp diff --git a/headers/wasm.hpp b/headers/wasm.hpp index c7e98b6e..36fe3849 100644 --- a/headers/wasm.hpp +++ b/headers/wasm.hpp @@ -3,5 +3,6 @@ #include "wasm/concrete_rt.hpp" #include "wasm/symbolic_rt.hpp" - +#include "wasm/concolic_driver.hpp" +#include "wasm/utils.hpp" #endif \ No newline at end of file diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp new file mode 100644 index 00000000..4307413b --- /dev/null +++ b/headers/wasm/concolic_driver.hpp @@ -0,0 +1,98 @@ +#ifndef CONCOLIC_DRIVER_HPP +#define CONCOLIC_DRIVER_HPP + +#include "smt_solver.hpp" +#include "symbolic_rt.hpp" +#include +#include +#include + +class ConcolicDriver { + friend class ManagedConcolicCleanup; + +public: + ConcolicDriver(std::function entrypoint, std::string tree_file) + : entrypoint(entrypoint), tree_file(tree_file) {} + ConcolicDriver(std::function entrypoint) + : entrypoint(entrypoint), tree_file(std::nullopt) {} + void run(); + +private: + Solver solver; + std::function entrypoint; + std::optional tree_file; +}; + +class ManagedConcolicCleanup { + const ConcolicDriver &driver; + +public: + ManagedConcolicCleanup(const ConcolicDriver &driver) : driver(driver) {} + ~ManagedConcolicCleanup() { + if (driver.tree_file.has_value()) + ExploreTree.dump_graphviz(driver.tree_file.value()); + } +}; + +inline void ConcolicDriver::run() { + ManagedConcolicCleanup cleanup{*this}; + while (true) { + auto cond = ExploreTree.get_unexplored_conditions(); + ExploreTree.reset_cursor(); + + if (!cond.has_value()) { + std::cout << "No unexplored conditions found, exiting..." << std::endl; + return; + } + auto new_env = solver.solve(cond.value()); + if (!new_env.has_value()) { + std::cout << "All unexplored paths are unreachable, exiting..." + << std::endl; + return; + } + SymEnv.update(std::move(new_env.value())); + try { + entrypoint(); + std::cout << "Execution finished successfully with symbolic environment:" + << std::endl; + std::cout << SymEnv.to_string() << std::endl; + } catch (...) { + ExploreTree.fillFailedNode(); + std::cout << "Caught runtime error with symbolic environment:" + << std::endl; + std::cout << SymEnv.to_string() << std::endl; + return; + } + } +} + +static std::monostate reset_stacks() { + Stack.reset(); + Frames.reset(); + SymStack.reset(); + SymFrames.reset(); + initRand(); + Memory = Memory_t(1); + return std::monostate{}; +} + +static void start_concolic_execution_with( + std::function entrypoint, + std::string tree_file) { + ConcolicDriver driver([=]() { entrypoint(std::monostate{}); }, tree_file); + driver.run(); +} + +static void start_concolic_execution_with( + std::function entrypoint) { + + const char *env_tree_file = std::getenv("TREE_FILE"); + + ConcolicDriver driver = + env_tree_file ? ConcolicDriver([=]() { entrypoint(std::monostate{}); }, + env_tree_file) + : ConcolicDriver([=]() { entrypoint(std::monostate{}); }); + driver.run(); +} + +#endif // CONCOLIC_DRIVER_HPP \ No newline at end of file diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index e994cbde..a0961453 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -52,8 +52,6 @@ static Num I32V(int v) { return v; } static Num I64V(int64_t v) { return v; } -using Slice = std::vector; - const int STACK_SIZE = 1024 * 64; class Stack_t { @@ -118,9 +116,12 @@ class Stack_t { } void initialize() { - // do nothing for now + // todo: remove this method + reset(); } + void reset() { count = 0; } + private: int32_t count; Num *stack_ptr; @@ -151,6 +152,8 @@ class Frames_t { count += size; } + void reset() { count = 0; } + private: int32_t count; Num *stack_ptr; diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp new file mode 100644 index 00000000..a3bbf78d --- /dev/null +++ b/headers/wasm/smt_solver.hpp @@ -0,0 +1,28 @@ +#ifndef SMT_SOLVER_HPP +#define SMT_SOLVER_HPP + +#include "concrete_rt.hpp" +#include "symbolic_rt.hpp" +#include +#include + +class Solver { +public: + Solver() : count(0) { + envs[0] = {Num(0), Num(0)}; + envs[1] = {Num(1), Num(2)}; + } + std::optional> solve(const std::vector &conditions) { + // here is just a placeholder implementation to simulate solving result + if (count >= envs.size()) { + return std::nullopt; // No more environments to return + } + return envs[count++ % envs.size()]; + } + +private: + std::array, 5> envs; + int count; +}; + +#endif // SMT_SOLVER_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index a97fd0dd..920bcad4 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -7,7 +7,9 @@ #include #include #include +#include #include +#include #include #include @@ -20,6 +22,7 @@ class Symbolic { class Symbol : public Symbolic { public: Symbol(int id) : id(id) {} + int get_id() const { return id; } private: int id; @@ -54,6 +57,7 @@ struct SymVal { SymVal leq(const SymVal &other) const; SymVal gt(const SymVal &other) const; SymVal geq(const SymVal &other) const; + SymVal negate() const; }; inline SymVal Concrete(Num num) { @@ -109,6 +113,9 @@ inline SymVal SymVal::geq(const SymVal &other) const { inline SymVal SymVal::is_zero() const { return SymVal(std::make_shared(EQ, *this, Concrete(I32V(0)))); } +inline SymVal SymVal::negate() const { + return SymVal(std::make_shared(EQ, *this, Concrete(I32V(0)))); +} inline SymVal SymVal::makeSymbolic() const { auto concrete = dynamic_cast(symptr.get()); @@ -137,6 +144,11 @@ class SymStack_t { SymVal peek() { return stack.back(); } + void reset() { + // Reset the symbolic stack + stack.clear(); + } + std::vector stack; }; @@ -165,6 +177,11 @@ class SymFrames_t { stack[stack.size() - 1 - index] = val; } + void reset() { + // Reset the symbolic frames + stack.clear(); + } + std::vector stack; }; @@ -190,14 +207,28 @@ struct Node { os << "}\n"; } - int get_next_id(int &id_counter) { return id_counter++; } - virtual int generate_dot(std::ostream &os, int parent_dot_id, - const std::string &edge_label) = 0; + virtual void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) = 0; protected: // Counter for unique node IDs across the entire graph, only for generating // graphviz purpose static int current_id; + void graphviz_node(std::ostream &os, const int node_id, + const std::string &label, const std::string &shape, + const std::string &fillcolor) { + os << " node" << node_id << " [label=\"" << label << "\", shape=" << shape + << ", style=filled, fillcolor=" << fillcolor << "];\n"; + } + + void graphviz_edge(std::ostream &os, int from_id, int target_id, + const std::string &edge_label) { + os << " node" << from_id << " -> node" << target_id; + if (!edge_label.empty()) { + os << " [label=\"" << edge_label << "\"]"; + } + os << ";\n"; + } }; // TODO: use this header file in multiple compilation units will cause problems @@ -234,21 +265,16 @@ struct IfElseNode : Node { return result; } - int generate_dot(std::ostream &os, int parent_dot_id, - const std::string &edge_label) override { + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { int current_node_dot_id = current_id; current_id += 1; - os << " node" << current_node_dot_id << " [label=\"If\"," - << "shape=diamond, fillcolor=lightyellow];\n"; + graphviz_node(os, current_node_dot_id, "If", "diamond", "lightyellow"); // Draw edge from parent if this is not the root node if (parent_dot_id != -1) { - os << " node" << parent_dot_id << " -> node" << current_node_dot_id; - if (!edge_label.empty()) { - os << " [label=\"" << edge_label << "\"]"; - } - os << ";\n"; + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); } assert(true_branch != nullptr); assert(true_branch->node != nullptr); @@ -256,7 +282,6 @@ struct IfElseNode : Node { assert(false_branch != nullptr); assert(false_branch->node != nullptr); false_branch->node->generate_dot(os, current_node_dot_id, "false"); - return current_node_dot_id; } }; @@ -265,39 +290,92 @@ struct UnExploredNode : Node { std::string to_string() override { return "UnexploredNode"; } protected: - int generate_dot(std::ostream &os, int parent_dot_id, - const std::string &edge_label) override { + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "Unexplored", "octagon", + "lightgrey"); + + if (parent_dot_id != -1) { + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); + } + } +}; + +struct Finished : Node { + Finished() {} + std::string to_string() override { return "FinishedNode"; } - os << " node" << current_node_dot_id - << " [label=\"Unexplored\", shape=octagon, style=filled, " - "fillcolor=lightgrey];\n"; +protected: + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "Finished", "box", "lightgreen"); if (parent_dot_id != -1) { - os << " node" << parent_dot_id << " -> node" << current_node_dot_id; - if (!edge_label.empty()) { - os << " [label=\"" << edge_label << "\"]"; - } - os << ";\n"; + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); } + } +}; + +struct Failed : Node { + Failed() {} + std::string to_string() override { return "FailedNode"; } - return current_node_dot_id; +protected: + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "Failed", "box", "red"); + + if (parent_dot_id != -1) { + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); + } } }; static UnExploredNode unexplored; inline NodeBox::NodeBox() - : node(std::make_unique< - UnExploredNode>() /* TODO: avoid allocation of unexplored node */) {} + : node(std::make_unique()), + /* TODO: avoid allocation of unexplored node */ + parent(nullptr) {} class ExploreTree_t { public: explicit ExploreTree_t() : root(std::make_unique()), cursor(root.get()) {} + + void reset_cursor() { + // Reset the cursor to the root of the tree + cursor = root.get(); + } + + std::monostate fillFinishedNode() { + if (dynamic_cast(cursor->node.get())) { + cursor->node = std::make_unique(); + } else { + assert(dynamic_cast(cursor->node.get()) != nullptr); + } + return std::monostate{}; + } + + std::monostate fillFailedNode() { + if (dynamic_cast(cursor->node.get())) { + cursor->node = std::make_unique(); + } else { + assert(dynamic_cast(cursor->node.get()) != nullptr); + } + return std::monostate{}; + } + std::monostate fillIfElseNode(SymVal cond) { - // fill the current node with an ifelse branch node - cursor->node = std::make_unique(cond); + // fill the current NodeBox with an ifelse branch node it's unexplored + if (dynamic_cast(cursor->node.get())) { + cursor->node = std::make_unique(cond); + } + assert(dynamic_cast(cursor->node.get()) != nullptr && + "Current node is not an IfElseNode, cannot fill it!"); return std::monostate(); } @@ -328,13 +406,60 @@ class ExploreTree_t { std::monostate dump_graphviz(std::string filepath) { std::ofstream ofs(filepath); if (!ofs.is_open()) { - throw std::runtime_error("Failed to open explore_tree.dot for writing"); + throw std::runtime_error("Failed to open " + filepath + " for writing"); } to_graphviz(ofs); return std::monostate(); } + std::optional> get_unexplored_conditions() { + // Get all unexplored conditions in the tree + std::vector result; + auto box = pick_unexplored(); + if (!box) { + return std::nullopt; + } + while (box->parent) { + auto parent = box->parent; + auto if_else_node = dynamic_cast(parent->node.get()); + if (if_else_node) { + if (if_else_node->true_branch.get() == box) { + // If the current box is the true branch, add the condition + result.push_back(if_else_node->cond); + } else if (if_else_node->false_branch.get() == box) { + // If the current box is the false branch, add the negated condition + result.push_back(if_else_node->cond.negate()); + } else { + throw std::runtime_error("Unexpected node structure in explore tree"); + } + } + // Move to parent + box = box->parent; + } + return result; + } + + NodeBox *pick_unexplored() { + // Pick an unexplored node from the tree + // For now, we just iterate through the tree and return the first unexplored + return pick_unexplored_of(root.get()); + } + private: + NodeBox *pick_unexplored_of(NodeBox *node) { + if (dynamic_cast(node->node.get()) != nullptr) { + return node; + } + auto if_else_node = dynamic_cast(node->node.get()); + if (if_else_node) { + NodeBox *result = pick_unexplored_of(if_else_node->true_branch.get()); + if (result) { + return result; + } + return pick_unexplored_of(if_else_node->false_branch.get()); + } + return nullptr; // No unexplored node found + } std::unique_ptr root; NodeBox *cursor; }; @@ -344,10 +469,28 @@ static ExploreTree_t ExploreTree; class SymEnv_t { public: Num read(SymVal sym) { - // Read a symbolic value from the symbolic environment - // For now, we just return a zero return Num(0); + auto symbol = dynamic_cast(sym.symptr.get()); + assert(symbol); + return map[symbol->get_id()]; } + + void update(std::vector new_env) { map = std::move(new_env); } + + std::string to_string() const { + std::string result; + result += "(\n"; + for (int i = 0; i < map.size(); ++i) { + const Num &num = map[i]; + result += + " (" + std::to_string(i) + "->" + std::to_string(num.value) + ")\n"; + } + result += ")"; + return result; + } + +private: + std::vector map; // The symbolic environment, a vector of Num }; static SymEnv_t SymEnv; diff --git a/headers/wasm/utils.hpp b/headers/wasm/utils.hpp new file mode 100644 index 00000000..8a86ac98 --- /dev/null +++ b/headers/wasm/utils.hpp @@ -0,0 +1,15 @@ +#ifndef UTILS_HPP +#define UTILS_HPP + +#ifndef GENSYM_ASSERT +#define GENSYM_ASSERT(condition) \ + do { \ + if (!(condition)) { \ + throw std::runtime_error(std::string("Assertion failed: ") + " (" + \ + __FILE__ + ":" + std::to_string(__LINE__) + \ + ")"); \ + } \ + } while (0) +#endif + +#endif // UTILS_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 3c342177..71463bf5 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -416,7 +416,7 @@ trait StagedWasmEvaluator extends SAIOps { } } val (instrs, locals) = (funBody.body, funBody.locals) - Stack.initialize() + resetStacks() Frames.pushFrame(locals) eval(instrs, (_: Context) => forwardKont, mkont, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) Frames.popFrame(locals.size) @@ -428,10 +428,7 @@ trait StagedWasmEvaluator extends SAIOps { if (printRes) { Stack.print() } - dumpTree match { - case Some(filePath) => ExploreTree.dumpGraphiviz(filePath) - case None => () - } + ExploreTree.fillWithFinished() "no-op".reflectCtrlWith[Unit]() } val temp: Rep[MCont[Unit]] = topFun(haltK) @@ -558,6 +555,7 @@ trait StagedWasmEvaluator extends SAIOps { object Memory { def storeInt(base: Rep[Int], offset: Int, value: Rep[Int]): Rep[Unit] = { "memory-store-int".reflectCtrlWith[Unit](base, offset, value) + // todo: store symbolic value to memory via extract/concat operation } def loadInt(base: Rep[Int], offset: Int): StagedNum = { @@ -570,6 +568,10 @@ trait StagedWasmEvaluator extends SAIOps { } } + def resetStacks(): Rep[Unit] = { + "reset-stacks".reflectCtrlWith[Unit]() + } + // call unreachable def unreachable(): Rep[Unit] = { "unreachable".reflectCtrlWith[Unit]() @@ -617,6 +619,10 @@ trait StagedWasmEvaluator extends SAIOps { "tree-fill-if-else".reflectCtrlWith[Unit](s) } + def fillWithFinished(): Rep[Unit] = { + "tree-fill-finished".reflectCtrlWith[Unit]() + } + def moveCursor(branch: Boolean): Rep[Unit] = { "tree-move-cursor".reflectCtrlWith[Unit](branch) } @@ -875,6 +881,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { } override def shallow(n: Node): Unit = n match { + case Node(_, "reset-stacks", _, _) => + emit("reset_stacks()") case Node(_, "frame-get", List(i), _) => emit("Frames.get("); shallow(i); emit(")") case Node(_, "sym-frame-get", List(i), _) => @@ -977,6 +985,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("assert("); shallow(cond); emit(")") case Node(_, "tree-fill-if-else", List(s), _) => emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") + case Node(_, "tree-fill-finished", List(), _) => + emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b), _) => emit("ExploreTree.moveCursor("); shallow(b); emit(")") case Node(_, "tree-print", List(), _) => From 9ab162fe0305be5c955154b6be9292befe8e4d70 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Fri, 18 Jul 2025 17:41:15 +0800 Subject: [PATCH 14/82] fix: add an unreachable node & use GENSYM_ASSERT --- headers/wasm/concolic_driver.hpp | 16 ++- headers/wasm/symbolic_rt.hpp | 128 ++++++++++++------ .../scala/wasm/StagedConcolicMiniWasm.scala | 2 +- 3 files changed, 97 insertions(+), 49 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 4307413b..9c35f161 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -37,18 +37,22 @@ class ManagedConcolicCleanup { inline void ConcolicDriver::run() { ManagedConcolicCleanup cleanup{*this}; while (true) { - auto cond = ExploreTree.get_unexplored_conditions(); ExploreTree.reset_cursor(); - if (!cond.has_value()) { - std::cout << "No unexplored conditions found, exiting..." << std::endl; + auto unexplored = ExploreTree.pick_unexplored(); + if (!unexplored) { + std::cout << "No unexplored nodes found, exiting..." << std::endl; return; } - auto new_env = solver.solve(cond.value()); + auto cond = unexplored->collect_path_conds(); + auto new_env = solver.solve(cond); if (!new_env.has_value()) { - std::cout << "All unexplored paths are unreachable, exiting..." + // TODO: current implementation is buggy, there could be other reachable + // unexplored paths + std::cout << "Found an unreachable path, marking it as unreachable..." << std::endl; - return; + unexplored->fillUnreachableNode(); + continue; } SymEnv.update(std::move(new_env.value())); try { diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 920bcad4..95f292b5 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -193,6 +193,13 @@ struct NodeBox { explicit NodeBox(); std::unique_ptr node; NodeBox *parent; + + std::monostate fillIfElseNode(SymVal cond); + std::monostate fillFinishedNode(); + std::monostate fillFailedNode(); + std::monostate fillUnreachableNode(); + + std::vector collect_path_conds(); }; struct Node { @@ -334,13 +341,87 @@ struct Failed : Node { } }; -static UnExploredNode unexplored; +struct Unreachable : Node { + Unreachable() {} + std::string to_string() override { return "UnreachableNode"; } + +protected: + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "Unreachable", "box", "orange"); + + if (parent_dot_id != -1) { + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); + } + } +}; inline NodeBox::NodeBox() : node(std::make_unique()), /* TODO: avoid allocation of unexplored node */ parent(nullptr) {} +inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { + // fill the current NodeBox with an ifelse branch node it's unexplored + if (dynamic_cast(node.get())) { + node = std::make_unique(cond); + } + assert(dynamic_cast(node.get()) != nullptr && + "Current node is not an IfElseNode, cannot fill it!"); + return std::monostate(); +} + +inline std::monostate NodeBox::fillFinishedNode() { + if (dynamic_cast(node.get())) { + node = std::make_unique(); + } else { + assert(dynamic_cast(node.get()) != nullptr); + } + return std::monostate(); +} + +inline std::monostate NodeBox::fillFailedNode() { + if (dynamic_cast(node.get())) { + node = std::make_unique(); + } else { + assert(dynamic_cast(node.get()) != nullptr); + } + return std::monostate(); +} + +inline std::monostate NodeBox::fillUnreachableNode() { + if (dynamic_cast(node.get())) { + node = std::make_unique(); + } else { + assert(dynamic_cast(node.get()) != nullptr); + } + return std::monostate(); +} + +inline std::vector NodeBox::collect_path_conds() { + auto box = this; + auto result = std::vector(); + while (box->parent) { + auto parent = box->parent; + auto if_else_node = dynamic_cast(parent->node.get()); + if (if_else_node) { + if (if_else_node->true_branch.get() == box) { + // If the current box is the true branch, add the condition + result.push_back(if_else_node->cond); + } else if (if_else_node->false_branch.get() == box) { + // If the current box is the false branch, add the negated condition + result.push_back(if_else_node->cond.negate()); + } else { + throw std::runtime_error("Unexpected node structure in explore tree"); + } + } + // Move to parent + box = box->parent; + } + return result; +} + class ExploreTree_t { public: explicit ExploreTree_t() @@ -351,32 +432,12 @@ class ExploreTree_t { cursor = root.get(); } - std::monostate fillFinishedNode() { - if (dynamic_cast(cursor->node.get())) { - cursor->node = std::make_unique(); - } else { - assert(dynamic_cast(cursor->node.get()) != nullptr); - } - return std::monostate{}; - } + std::monostate fillFinishedNode() { return cursor->fillFinishedNode(); } - std::monostate fillFailedNode() { - if (dynamic_cast(cursor->node.get())) { - cursor->node = std::make_unique(); - } else { - assert(dynamic_cast(cursor->node.get()) != nullptr); - } - return std::monostate{}; - } + std::monostate fillFailedNode() { return cursor->fillFailedNode(); } std::monostate fillIfElseNode(SymVal cond) { - // fill the current NodeBox with an ifelse branch node it's unexplored - if (dynamic_cast(cursor->node.get())) { - cursor->node = std::make_unique(cond); - } - assert(dynamic_cast(cursor->node.get()) != nullptr && - "Current node is not an IfElseNode, cannot fill it!"); - return std::monostate(); + return cursor->fillIfElseNode(cond); } std::monostate moveCursor(bool branch) { @@ -419,24 +480,7 @@ class ExploreTree_t { if (!box) { return std::nullopt; } - while (box->parent) { - auto parent = box->parent; - auto if_else_node = dynamic_cast(parent->node.get()); - if (if_else_node) { - if (if_else_node->true_branch.get() == box) { - // If the current box is the true branch, add the condition - result.push_back(if_else_node->cond); - } else if (if_else_node->false_branch.get() == box) { - // If the current box is the false branch, add the negated condition - result.push_back(if_else_node->cond.negate()); - } else { - throw std::runtime_error("Unexpected node structure in explore tree"); - } - } - // Move to parent - box = box->parent; - } - return result; + return box->collect_path_conds(); } NodeBox *pick_unexplored() { diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 71463bf5..eb8d3aab 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -982,7 +982,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "sym-env-read", List(sym), _) => emit("SymEnv.read("); shallow(sym); emit(")") case Node(_, "assert-true", List(cond), _) => - emit("assert("); shallow(cond); emit(")") + emit("GENSYM_ASSERT("); shallow(cond); emit(")") case Node(_, "tree-fill-if-else", List(s), _) => emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") case Node(_, "tree-fill-finished", List(), _) => From b75a627a59c88ac7738b7bf4c8a7944e74b5f6b1 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 19 Jul 2025 13:20:40 +0800 Subject: [PATCH 15/82] call z3 to solve constraints --- headers/wasm/concolic_driver.hpp | 13 ++-- headers/wasm/smt_solver.hpp | 120 ++++++++++++++++++++++++++++--- headers/wasm/symbolic_rt.hpp | 39 ++++++---- 3 files changed, 145 insertions(+), 27 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 9c35f161..ea28d082 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -1,11 +1,13 @@ #ifndef CONCOLIC_DRIVER_HPP #define CONCOLIC_DRIVER_HPP +#include "concrete_rt.hpp" #include "smt_solver.hpp" #include "symbolic_rt.hpp" #include #include #include +#include class ConcolicDriver { friend class ManagedConcolicCleanup; @@ -45,16 +47,19 @@ inline void ConcolicDriver::run() { return; } auto cond = unexplored->collect_path_conds(); - auto new_env = solver.solve(cond); - if (!new_env.has_value()) { + std::vector new_env; + std::set valid_ids; + auto result = solver.solve(cond); + if (!result.has_value()) { // TODO: current implementation is buggy, there could be other reachable // unexplored paths std::cout << "Found an unreachable path, marking it as unreachable..." << std::endl; unexplored->fillUnreachableNode(); - continue; + continue; } - SymEnv.update(std::move(new_env.value())); + std::tie(new_env, valid_ids) = std::move(result.value()); + SymEnv.update(std::move(new_env), std::move(valid_ids)); try { entrypoint(); std::cout << "Execution finished successfully with symbolic environment:" diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index a3bbf78d..8e3f82e4 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -3,26 +3,124 @@ #include "concrete_rt.hpp" #include "symbolic_rt.hpp" +#include "z3++.h" #include +#include +#include +#include #include class Solver { public: - Solver() : count(0) { - envs[0] = {Num(0), Num(0)}; - envs[1] = {Num(1), Num(2)}; - } - std::optional> solve(const std::vector &conditions) { - // here is just a placeholder implementation to simulate solving result - if (count >= envs.size()) { - return std::nullopt; // No more environments to return + Solver() {} + std::optional, std::set>> + solve(const std::vector &conditions) { + // make an conjunction of all conditions + z3::expr conjunction = z3_ctx.bool_val(true); + for (const auto &cond : conditions) { + auto z3_cond = build_z3_expr(cond); + conjunction = conjunction && z3_cond != z3_ctx.bv_val(0, 32); + } +#ifdef DEBUG + std::cout << "Symbolic conditions size: " << conditions.size() << std::endl; + std::cout << "Solving conditions: " << conjunction << std::endl; +#endif + // call z3 to solve the condition + z3::solver z3_solver(z3_ctx); + z3_solver.add(conjunction); + switch (z3_solver.check()) { + case z3::unsat: + return std::nullopt; // No solution found + case z3::sat: { + z3::model model = z3_solver.get_model(); + std::vector result(max_id + 1, Num(0)); + // Reference: + // https://github.com/Z3Prover/z3/blob/master/examples/c%2B%2B/example.cpp#L59 + + std::cout << "Solved Z3 model" << model << std::endl; + std::set seen_ids; + for (unsigned i = 0; i < model.size(); ++i) { + z3::func_decl var = model[i]; + z3::expr value = model.get_const_interp(var); + std::string name = var.name().str(); + if (name.starts_with("s_")) { + int id = std::stoi(name.substr(2)); + seen_ids.insert(id); + result[id] = Num(value.get_numeral_int()); + } else { + std::cout << "Find a variable that is not created by GenSym: " << name + << std::endl; + } + } + return std::make_tuple(result, seen_ids); } - return envs[count++ % envs.size()]; + case z3::unknown: + throw std::runtime_error("Z3 solver returned unknown status"); + } + return std::nullopt; // Should not reach here } private: - std::array, 5> envs; - int count; + z3::context z3_ctx; + z3::expr build_z3_expr(const SymVal &sym_val); }; +inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) { + if (auto sym = std::dynamic_pointer_cast(sym_val.symptr)) { + return z3_ctx.bv_const(("s_" + std::to_string(sym->get_id())).c_str(), 32); + } else if (auto concrete = + std::dynamic_pointer_cast(sym_val.symptr)) { + return z3_ctx.bv_val(concrete->value.value, 32); + } else if (auto binary = + std::dynamic_pointer_cast(sym_val.symptr)) { + auto bit_width = 32; + z3::expr zero_bv = + z3_ctx.bv_val(0, bit_width); // Represents 0 as a 32-bit bitvector + z3::expr one_bv = + z3_ctx.bv_val(1, bit_width); // Represents 1 as a 32-bit bitvector + + z3::expr left = build_z3_expr(binary->lhs); + z3::expr right = build_z3_expr(binary->rhs); + // TODO: make sure the semantics of these operations are aligned with wasm + switch (binary->op) { + case EQ: { + auto temp_bool = left == right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case NEQ: { + auto temp_bool = left != right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case LT: { + auto temp_bool = left < right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case LEQ: { + auto temp_bool = left <= right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case GT: { + auto temp_bool = left > right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case GEQ: { + auto temp_bool = left >= right; + return z3::ite(temp_bool, one_bv, zero_bv); + } + case ADD: { + return left + right; + } + case SUB: { + return left - right; + } + case MUL: { + return left * right; + } + case DIV: { + return left / right; + } + } + } + throw std::runtime_error("Unsupported symbolic value type"); +} #endif // SMT_SOLVER_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 95f292b5..3e7ea2cc 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,9 +20,13 @@ class Symbolic { virtual ~Symbolic() = default; // Make Symbolic polymorphic }; +static int max_id = 0; + class Symbol : public Symbolic { public: - Symbol(int id) : id(id) {} + // TODO: add type information to determine the size of bitvector + // for now we just assume that only i32 will be used + Symbol(int id) : id(id) { max_id = std::max(max_id, id); } int get_id() const { return id; } private: @@ -190,7 +195,7 @@ static SymFrames_t SymFrames; struct Node; struct NodeBox { - explicit NodeBox(); + explicit NodeBox(NodeBox *parent); std::unique_ptr node; NodeBox *parent; @@ -247,9 +252,9 @@ struct IfElseNode : Node { std::unique_ptr true_branch; std::unique_ptr false_branch; - IfElseNode(SymVal cond) - : cond(cond), true_branch(std::make_unique()), - false_branch(std::make_unique()) {} + IfElseNode(SymVal cond, NodeBox *parent) + : cond(cond), true_branch(std::make_unique(parent)), + false_branch(std::make_unique(parent)) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -357,15 +362,15 @@ struct Unreachable : Node { } }; -inline NodeBox::NodeBox() +inline NodeBox::NodeBox(NodeBox *parent) : node(std::make_unique()), /* TODO: avoid allocation of unexplored node */ - parent(nullptr) {} + parent(parent) {} inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { // fill the current NodeBox with an ifelse branch node it's unexplored if (dynamic_cast(node.get())) { - node = std::make_unique(cond); + node = std::make_unique(cond, this); } assert(dynamic_cast(node.get()) != nullptr && "Current node is not an IfElseNode, cannot fill it!"); @@ -425,7 +430,7 @@ inline std::vector NodeBox::collect_path_conds() { class ExploreTree_t { public: explicit ExploreTree_t() - : root(std::make_unique()), cursor(root.get()) {} + : root(std::make_unique(nullptr)), cursor(root.get()) {} void reset_cursor() { // Reset the cursor to the root of the tree @@ -513,13 +518,22 @@ static ExploreTree_t ExploreTree; class SymEnv_t { public: Num read(SymVal sym) { - return Num(0); auto symbol = dynamic_cast(sym.symptr.get()); assert(symbol); + if (symbol->get_id() >= map.size()) { + map.resize(symbol->get_id() + 1); + } +#if DEBUG + std::cout << "Read symbol: " << symbol->get_id() + << " from symbolic environment" << std::endl; + std::cout << "Current symbolic environment: " << to_string() << std::endl; +#endif return map[symbol->get_id()]; } - void update(std::vector new_env) { map = std::move(new_env); } + void update(std::vector new_env, std::set valid_ids) { + map = std::move(new_env); + } std::string to_string() const { std::string result; @@ -534,7 +548,8 @@ class SymEnv_t { } private: - std::vector map; // The symbolic environment, a vector of Num + std::vector map; // The symbolic environment, a vector of Num + std::set valid_ids; // The set of valid IDs in the symbolic environment }; static SymEnv_t SymEnv; From 26c9917fcb39e84f33318955fb3a9b3a3fd9fb32 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 19 Jul 2025 17:48:20 +0800 Subject: [PATCH 16/82] remove unused & resize before update environment --- headers/wasm/concolic_driver.hpp | 6 ++---- headers/wasm/smt_solver.hpp | 14 +++++++------- headers/wasm/symbolic_rt.hpp | 3 +-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index ea28d082..8e8ca815 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -47,8 +47,6 @@ inline void ConcolicDriver::run() { return; } auto cond = unexplored->collect_path_conds(); - std::vector new_env; - std::set valid_ids; auto result = solver.solve(cond); if (!result.has_value()) { // TODO: current implementation is buggy, there could be other reachable @@ -58,8 +56,8 @@ inline void ConcolicDriver::run() { unexplored->fillUnreachableNode(); continue; } - std::tie(new_env, valid_ids) = std::move(result.value()); - SymEnv.update(std::move(new_env), std::move(valid_ids)); + auto new_env = result.value(); + SymEnv.update(std::move(new_env)); try { entrypoint(); std::cout << "Execution finished successfully with symbolic environment:" diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 8e3f82e4..de5b80cb 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -13,8 +13,7 @@ class Solver { public: Solver() {} - std::optional, std::set>> - solve(const std::vector &conditions) { + std::optional> solve(const std::vector &conditions) { // make an conjunction of all conditions z3::expr conjunction = z3_ctx.bool_val(true); for (const auto &cond : conditions) { @@ -33,26 +32,27 @@ class Solver { return std::nullopt; // No solution found case z3::sat: { z3::model model = z3_solver.get_model(); - std::vector result(max_id + 1, Num(0)); + std::vector result; // Reference: // https://github.com/Z3Prover/z3/blob/master/examples/c%2B%2B/example.cpp#L59 - std::cout << "Solved Z3 model" << model << std::endl; - std::set seen_ids; + std::cout << "Solved Z3 model" << std::endl << model << std::endl; for (unsigned i = 0; i < model.size(); ++i) { z3::func_decl var = model[i]; z3::expr value = model.get_const_interp(var); std::string name = var.name().str(); if (name.starts_with("s_")) { int id = std::stoi(name.substr(2)); - seen_ids.insert(id); + if (id >= result.size()) { + result.resize(id + 1); + } result[id] = Num(value.get_numeral_int()); } else { std::cout << "Find a variable that is not created by GenSym: " << name << std::endl; } } - return std::make_tuple(result, seen_ids); + return result; } case z3::unknown: throw std::runtime_error("Z3 solver returned unknown status"); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 3e7ea2cc..18629c80 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -531,7 +531,7 @@ class SymEnv_t { return map[symbol->get_id()]; } - void update(std::vector new_env, std::set valid_ids) { + void update(std::vector new_env) { map = std::move(new_env); } @@ -549,7 +549,6 @@ class SymEnv_t { private: std::vector map; // The symbolic environment, a vector of Num - std::set valid_ids; // The set of valid IDs in the symbolic environment }; static SymEnv_t SymEnv; From 319cfd6576f0399bcfdd3668e0a19b9feeadcad2 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 23 Jul 2025 14:11:42 +0800 Subject: [PATCH 17/82] use c++20 --- src/main/scala/wasm/StagedConcolicMiniWasm.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index eb8d3aab..922d2113 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -1080,7 +1080,7 @@ object WasmToCppCompiler { } import sys.process._ - val command = s"g++ -std=c++17 $outputCpp -o $outputExe -O3 -g " + generated.headerFolders.map(f => s"-I$f").mkString(" ") + val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g " + generated.headerFolders.map(f => s"-I$f").mkString(" ") if (command.! != 0) { throw new RuntimeException(s"Compilation failed for $outputCpp") } From 8f45912f6275c9dc5a5ee8bab34b02bcae3b5609 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 23 Jul 2025 19:28:50 +0800 Subject: [PATCH 18/82] branch in brtable --- benchmarks/wasm/staged/brtable_concolic.wat | 22 +++++++++++++++++++ headers/wasm/smt_solver.hpp | 2 +- .../scala/wasm/StagedConcolicMiniWasm.scala | 17 +++++++++++--- .../genwasym/TestStagedConcolicEval.scala | 4 ++++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 benchmarks/wasm/staged/brtable_concolic.wat diff --git a/benchmarks/wasm/staged/brtable_concolic.wat b/benchmarks/wasm/staged/brtable_concolic.wat new file mode 100644 index 00000000..04429e90 --- /dev/null +++ b/benchmarks/wasm/staged/brtable_concolic.wat @@ -0,0 +1,22 @@ +(module $brtable + (global (;0;) (mut i32) (i32.const 1048576)) + (type (;0;) (func (param i32))) + (func (;0;) (type 1) (result i32) + i32.const 2 + (block + (block + (block + i32.const 0 + i32.symbolic + br_table 0 1 2 0 ;; br_table will consume an element from the stack + ) + i32.const 1 + call 1 + br 1 + ) + i32.const 0 + call 1 + ) + ) + (import "console" "assert" (func (type 0))) + (start 0)) diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index de5b80cb..f2450905 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -46,7 +46,7 @@ class Solver { if (id >= result.size()) { result.resize(id + 1); } - result[id] = Num(value.get_numeral_int()); + result[id] = Num(value.get_numeral_int64()); } else { std::cout << "Find a variable that is not created by GenSym: " << name << std::endl; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 922d2113..6c8e45aa 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -17,6 +17,7 @@ import gensym.wasm.symbolic.{SymVal} import gensym.lmsx.{SAIDriver, StringOps, SAIOps, SAICodeGenBase, CppSAIDriver, CppSAICodeGenBase} import gensym.wasm.symbolic.Concrete import gensym.wasm.symbolic.ExploreTree +import gensym.structure.freer.Explore @virtualize trait StagedWasmEvaluator extends SAIOps { @@ -270,12 +271,20 @@ trait StagedWasmEvaluator extends SAIOps { } () case BrTable(labels, default) => - val (cond, newCtx) = Stack.pop() + val (label, newCtx) = Stack.pop() def aux(choices: List[Int], idx: Int): Rep[Unit] = { if (choices.isEmpty) trail(default)(newCtx)(mkont) else { - if (cond.toInt == idx) trail(choices.head)(newCtx)(mkont) - else aux(choices.tail, idx + 1) + val cond = (label - toStagedNum(I32V(idx))).isZero() + ExploreTree.fillWithIfElse(cond.s) + if (cond.toInt != 0) { + ExploreTree.moveCursor(true) + trail(choices.head)(newCtx)(mkont) + } + else { + ExploreTree.moveCursor(false) + aux(choices.tail, idx + 1) + } } } aux(labels, 0) @@ -959,6 +968,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(" >= "); shallow(rhs) case Node(_, "sym-binary-add", List(lhs, rhs), _) => shallow(lhs); emit(".add("); shallow(rhs); emit(")") + case Node(_, "sym-binary-sub", List(lhs, rhs), _) => + shallow(lhs); emit(".minus("); shallow(rhs); emit(")") case Node(_, "sym-binary-mul", List(lhs, rhs), _) => shallow(lhs); emit(".mul("); shallow(rhs); emit(")") case Node(_, "sym-binary-div", List(lhs, rhs), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 77868e2c..fa7f704b 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -35,4 +35,8 @@ class TestStagedConcolicEval extends FunSuite { test("bug-finding") { testFileToCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) } + + test("brtable-bug-finding") { + testFileToCpp("./benchmarks/wasm/staged/brtable_concolic.wat") + } } From 2e2259d0bbd18aa122d201d62bc03d245c6ec191 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 23 Jul 2025 19:32:49 +0800 Subject: [PATCH 19/82] use driver's entrypoint by default --- src/main/scala/wasm/StagedConcolicMiniWasm.scala | 4 ++-- src/test/scala/genwasym/TestStagedConcolicEval.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 6c8e45aa..833bbc9b 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -1047,7 +1047,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { |End of Generated Code |*******************************************/ |int main(int argc, char *argv[]) { - | Snippet(std::monostate{}); + | start_concolic_execution_with(Snippet); | return 0; |}""".stripMargin) } @@ -1091,7 +1091,7 @@ object WasmToCppCompiler { } import sys.process._ - val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g " + generated.headerFolders.map(f => s"-I$f").mkString(" ") + val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g -l z3 " + generated.headerFolders.map(f => s"-I$f").mkString(" ") if (command.! != 0) { throw new RuntimeException(s"Compilation failed for $outputCpp") } diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index fa7f704b..a65d0eda 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -30,7 +30,7 @@ class TestStagedConcolicEval extends FunSuite { }) } - test("ack-cpp") { testFileToCpp("./benchmarks/wasm/ack.wat", Some("real_main"), expect=Some(List(7))) } + test("ack-cpp") { testFileToCpp("./benchmarks/wasm/ack.wat", Some("real_main")) } test("bug-finding") { testFileToCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) From 2b42b277cfa42e6d06ba49f70daba327c4c4abcf Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 23 Jul 2025 20:09:12 +0800 Subject: [PATCH 20/82] rename package name of staged miniwasm --- src/main/scala/wasm/StagedMiniWasm.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/wasm/StagedMiniWasm.scala b/src/main/scala/wasm/StagedMiniWasm.scala index bfa2082d..ea9dc9c6 100644 --- a/src/main/scala/wasm/StagedMiniWasm.scala +++ b/src/main/scala/wasm/StagedMiniWasm.scala @@ -1,4 +1,4 @@ -package gensym.wasm.miniwasm +package gensym.wasm.stagedminiwasm import scala.collection.mutable.{ArrayBuffer, HashMap} @@ -12,6 +12,7 @@ import lms.core.Graph import gensym.wasm.ast._ import gensym.wasm.ast.{Const => WasmConst, Block => WasmBlock} +import gensym.wasm.miniwasm.ModuleInstance import gensym.lmsx.{SAIDriver, StringOps, SAIOps, SAICodeGenBase, CppSAIDriver, CppSAICodeGenBase} @virtualize From 619a8f022d015d67ccbc4919bc49801175dc9dda Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 23 Jul 2025 20:15:29 +0800 Subject: [PATCH 21/82] tweak --- src/test/scala/genwasym/TestStagedEval.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/scala/genwasym/TestStagedEval.scala b/src/test/scala/genwasym/TestStagedEval.scala index d4d1e960..3769428f 100644 --- a/src/test/scala/genwasym/TestStagedEval.scala +++ b/src/test/scala/genwasym/TestStagedEval.scala @@ -6,6 +6,7 @@ import lms.core.stub.Adapter import gensym.wasm.parser._ import gensym.wasm.miniwasm._ +import gensym.wasm.stagedminiwasm._ class TestStagedEval extends FunSuite { def testFileToScala(filename: String, main: Option[String] = None, printRes: Boolean = false) = { From af6751aca613e013efc78e751b0dd1a4e0b420e6 Mon Sep 17 00:00:00 2001 From: butterunderflow <112108686+butterunderflow@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:09:08 -0400 Subject: [PATCH 22/82] Reuse symbolic states (#90) 1. split concrete and symbolic interpreter 2. copy tests from concrete execution 3. some bug fixes --- benchmarks/wasm/staged/return_poly.wat | 19 + headers/wasm/concolic_driver.hpp | 23 +- headers/wasm/concrete_rt.hpp | 6 +- headers/wasm/controls.hpp | 5 + headers/wasm/smt_solver.hpp | 8 +- headers/wasm/symbolic_rt.hpp | 146 +- headers/wasm/utils.hpp | 24 + .../scala/wasm/StagedConcolicMiniWasm.scala | 1234 +++++++++++++---- .../genwasym/TestStagedConcolicEval.scala | 70 +- 9 files changed, 1198 insertions(+), 337 deletions(-) create mode 100644 benchmarks/wasm/staged/return_poly.wat create mode 100644 headers/wasm/controls.hpp diff --git a/benchmarks/wasm/staged/return_poly.wat b/benchmarks/wasm/staged/return_poly.wat new file mode 100644 index 00000000..1bab5ef0 --- /dev/null +++ b/benchmarks/wasm/staged/return_poly.wat @@ -0,0 +1,19 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + ;; TODO: It seems that our parser or preprocessor has some problems; the result type of the last line doesn't take effect + (func (result i32) + block + i32.const 21 + i32.const 35 + i32.const 42 + return + end + i32.const 100 + ) + (func (type 0) + call 0 + ;; unreachable + ) + (export "$real_main" (func 1)) +) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 8e8ca815..427a0de8 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -4,6 +4,7 @@ #include "concrete_rt.hpp" #include "smt_solver.hpp" #include "symbolic_rt.hpp" +#include "utils.hpp" #include #include #include @@ -43,33 +44,33 @@ inline void ConcolicDriver::run() { auto unexplored = ExploreTree.pick_unexplored(); if (!unexplored) { - std::cout << "No unexplored nodes found, exiting..." << std::endl; + GENSYM_INFO("No unexplored nodes found, exiting..."); return; } auto cond = unexplored->collect_path_conds(); auto result = solver.solve(cond); if (!result.has_value()) { - // TODO: current implementation is buggy, there could be other reachable - // unexplored paths - std::cout << "Found an unreachable path, marking it as unreachable..." - << std::endl; + GENSYM_INFO("Found an unreachable path, marking it as unreachable..."); unexplored->fillUnreachableNode(); continue; } auto new_env = result.value(); SymEnv.update(std::move(new_env)); try { + GENSYM_INFO("Now execute the program with symbolic environment: "); + GENSYM_INFO(SymEnv.to_string()); entrypoint(); - std::cout << "Execution finished successfully with symbolic environment:" - << std::endl; - std::cout << SymEnv.to_string() << std::endl; + GENSYM_INFO("Execution finished successfully with symbolic environment:"); + GENSYM_INFO(SymEnv.to_string()); } catch (...) { ExploreTree.fillFailedNode(); - std::cout << "Caught runtime error with symbolic environment:" - << std::endl; - std::cout << SymEnv.to_string() << std::endl; + GENSYM_INFO("Caught runtime error with symbolic environment:"); + GENSYM_INFO(SymEnv.to_string()); return; } +#if defined(RUN_ONCE) + return; +#endif } } diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index a0961453..a9abccf2 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -72,9 +72,7 @@ class Stack_t { Num pop() { #ifdef DEBUG - if (count == 0) { - throw std::runtime_error("Stack underflow"); - } + assert(count > 0 && "Stack underflow"); #endif Num num = stack_ptr[count - 1]; count--; @@ -117,7 +115,7 @@ class Stack_t { void initialize() { // todo: remove this method - reset(); + reset(); } void reset() { count = 0; } diff --git a/headers/wasm/controls.hpp b/headers/wasm/controls.hpp new file mode 100644 index 00000000..16fa5136 --- /dev/null +++ b/headers/wasm/controls.hpp @@ -0,0 +1,5 @@ +#include +#include + +using MCont_t = std::function; +using Cont_t = std::function; \ No newline at end of file diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index f2450905..bc8cc9f9 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -3,6 +3,7 @@ #include "concrete_rt.hpp" #include "symbolic_rt.hpp" +#include "utils.hpp" #include "z3++.h" #include #include @@ -35,8 +36,8 @@ class Solver { std::vector result; // Reference: // https://github.com/Z3Prover/z3/blob/master/examples/c%2B%2B/example.cpp#L59 - - std::cout << "Solved Z3 model" << std::endl << model << std::endl; + GENSYM_INFO("Solved Z3 model"); + GENSYM_INFO(model); for (unsigned i = 0; i < model.size(); ++i) { z3::func_decl var = model[i]; z3::expr value = model.get_const_interp(var); @@ -48,8 +49,7 @@ class Solver { } result[id] = Num(value.get_numeral_int64()); } else { - std::cout << "Find a variable that is not created by GenSym: " << name - << std::endl; + GENSYM_INFO("Find a variable that is not created by GenSym: " + name); } } return result; diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 18629c80..94351f07 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -2,7 +2,9 @@ #define WASM_SYMBOLIC_RT_HPP #include "concrete_rt.hpp" +#include "controls.hpp" #include +#include #include #include #include @@ -22,6 +24,12 @@ class Symbolic { static int max_id = 0; +#ifdef NO_REUSE +static bool REUSE_MODE = false; +#else +static bool REUSE_MODE = true; +#endif + class Symbol : public Symbolic { public: // TODO: add type information to determine the size of bitvector @@ -65,6 +73,10 @@ struct SymVal { SymVal negate() const; }; +static SymVal make_symbolic(int index) { + return SymVal(std::make_shared(index)); +} + inline SymVal Concrete(Num num) { return SymVal(std::make_shared(num)); } @@ -133,6 +145,8 @@ inline SymVal SymVal::makeSymbolic() const { } } +class Snapshot_t; + class SymStack_t { public: void push(SymVal val) { @@ -142,6 +156,11 @@ class SymStack_t { SymVal pop() { // Pop a symbolic value from the stack + +#ifdef DEBUG + printf("[Debug] poping from stack, size of symbolic stack is: %zu\n", + stack.size()); +#endif auto ret = stack.back(); stack.pop_back(); return ret; @@ -149,11 +168,25 @@ class SymStack_t { SymVal peek() { return stack.back(); } + std::monostate shift(int32_t offset, int32_t size) { + auto n = stack.size(); + for (size_t i = n - size; i < n; ++i) { + stack[i - offset] = stack[i]; + } + stack.resize(n - offset); + return std::monostate(); + } + void reset() { // Reset the symbolic stack stack.clear(); } + void reuse(Snapshot_t snapshot); + + size_t size() const { return stack.size(); } + +private: std::vector stack; }; @@ -187,9 +220,46 @@ class SymFrames_t { stack.clear(); } + void reuse(Snapshot_t snapshot); + std::vector stack; }; +// A snapshot of the symbolic state and execution context (control) +class Snapshot_t { +public: + explicit Snapshot_t(); + + SymStack_t get_stack() const { return stack; } + SymFrames_t get_frames() const { return frames; } + +private: + SymStack_t stack; + SymFrames_t frames; +}; + +inline void SymStack_t::reuse(Snapshot_t snapshot) { +// Reusing the symbolic stack from the snapshot +#ifdef DEBUG + std::cout << "Reusing symbolic state from snapshot" << std::endl; + std::cout << "Old stack size = " << stack.size() << std::endl; + std::cout << "New stack size = " << snapshot.get_stack().stack.size() + << std::endl; +#endif + stack = snapshot.get_stack().stack; +} + +inline void SymFrames_t::reuse(Snapshot_t snapshot) { +// Reusing the symbolic frames from the snapshot +#ifdef DEBUG + std::cout << "Reusing symbolic state from snapshot" << std::endl; + std::cout << "Old frame size = " << stack.size() << std::endl; + std::cout << "New frame size = " << snapshot.get_frames().stack.size() + << std::endl; +#endif + stack = snapshot.get_frames().stack; +} + static SymFrames_t SymFrames; struct Node; @@ -199,7 +269,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond); + std::monostate fillIfElseNode(SymVal cond, const Snapshot_t &snapshot); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -251,8 +321,9 @@ struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; + Snapshot_t snapshot; - IfElseNode(SymVal cond, NodeBox *parent) + IfElseNode(SymVal cond, NodeBox *parent, Snapshot_t snapshot) : cond(cond), true_branch(std::make_unique(parent)), false_branch(std::make_unique(parent)) {} @@ -367,13 +438,15 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { - // fill the current NodeBox with an ifelse branch node it's unexplored +inline std::monostate NodeBox::fillIfElseNode(SymVal cond, + const Snapshot_t &snapshot) { + // fill the current NodeBox with an ifelse branch node when it's unexplored if (dynamic_cast(node.get())) { - node = std::make_unique(cond, this); + node = std::make_unique(cond, this, snapshot); } - assert(dynamic_cast(node.get()) != nullptr && - "Current node is not an IfElseNode, cannot fill it!"); + assert( + dynamic_cast(node.get()) != nullptr && + "Current node is not an Unexplored nor an IfElseNode, cannot fill it!"); return std::monostate(); } @@ -427,6 +500,32 @@ inline std::vector NodeBox::collect_path_conds() { return result; } +class Reuse_t { +public: + Reuse_t() : reuse_flag(false) {} + bool is_reusing() { + // we are in reuse mode and the flag is set + return REUSE_MODE && reuse_flag; + } + + void turn_on_reusing() { reuse_flag = true; } + + void turn_off_reusing() { reuse_flag = false; } + +private: + bool reuse_flag; +}; + +static Reuse_t Reuse; + +inline Snapshot_t::Snapshot_t() : stack(SymStack), frames(SymFrames) { +#ifdef DEBUG + std::cout << "Creating snapshot of size " << stack.size() << std::endl; +#endif + assert(!Reuse.is_reusing() && + "Creating snapshot while reusing the symbolic stack"); +} + class ExploreTree_t { public: explicit ExploreTree_t() @@ -435,14 +534,19 @@ class ExploreTree_t { void reset_cursor() { // Reset the cursor to the root of the tree cursor = root.get(); + Reuse.turn_off_reusing(); + // if root cursor is a branch node, then we can reuse the snapshot inside it + if (auto ite = dynamic_cast(cursor->node.get())) { + Reuse.turn_on_reusing(); + } } std::monostate fillFinishedNode() { return cursor->fillFinishedNode(); } std::monostate fillFailedNode() { return cursor->fillFailedNode(); } - std::monostate fillIfElseNode(SymVal cond) { - return cursor->fillIfElseNode(cond); + std::monostate fillIfElseNode(SymVal cond, const Snapshot_t &snapshot) { + return cursor->fillIfElseNode(cond, snapshot); } std::monostate moveCursor(bool branch) { @@ -456,6 +560,24 @@ class ExploreTree_t { } else { cursor = if_else_node->false_branch.get(); } + + if (dynamic_cast(cursor->node.get())) { + // If we meet an unexplored node, resume the snapshot before and keep + // going + +#ifdef DEBUG + std::cout << "Resuming snapshot for unexplored node" << std::endl; +#endif + if (Reuse.is_reusing()) { + Reuse.turn_off_reusing(); + SymStack.reuse(if_else_node->snapshot); + } + } else if (dynamic_cast(cursor->node.get())) { + // if we are moving to a branch node, we must have reused the symbolic + // states + assert((!REUSE_MODE || Reuse.is_reusing()) && + "Moving to a branch node without reusing symbolic states"); + } return std::monostate(); } @@ -531,9 +653,7 @@ class SymEnv_t { return map[symbol->get_id()]; } - void update(std::vector new_env) { - map = std::move(new_env); - } + void update(std::vector new_env) { map = std::move(new_env); } std::string to_string() const { std::string result; @@ -548,7 +668,7 @@ class SymEnv_t { } private: - std::vector map; // The symbolic environment, a vector of Num + std::vector map; // The symbolic environment, a vector of Num }; static SymEnv_t SymEnv; diff --git a/headers/wasm/utils.hpp b/headers/wasm/utils.hpp index 8a86ac98..ba57a1df 100644 --- a/headers/wasm/utils.hpp +++ b/headers/wasm/utils.hpp @@ -12,4 +12,28 @@ } while (0) #endif +#ifndef NO_DBG +#define GENSYM_DBG(obj) \ + do { \ + std::cout << "LOG: " << obj << " (" << __FILE__ << ":" \ + << std::to_string(__LINE__) << ")" << std::endl; \ + } while (0) +#else +#define GENSYM_LOG(message) \ + do { \ + } while (0) +#endif + +#ifndef NO_INFO +#define GENSYM_INFO(obj) \ + do { \ + std::cout << obj << std::endl; \ + } while (0) +#else +#define GENSYM_INFO(message) \ + do { \ + } while (0) + +#endif + #endif // UTILS_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 833bbc9b..769a0b85 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -26,28 +26,57 @@ trait StagedWasmEvaluator extends SAIOps { trait ReturnSite trait StagedNum { + def tipe: ValueType + } + + trait StagedConcreteNum { def tipe: ValueType = this match { - case I32(_, _) => NumType(I32Type) - case I64(_, _) => NumType(I64Type) - case F32(_, _) => NumType(F32Type) - case F64(_, _) => NumType(F64Type) + case I32C(_) => NumType(I32Type) + case I64C(_) => NumType(I64Type) + case F32C(_) => NumType(F32Type) + case F64C(_) => NumType(F64Type) } def i: Rep[Num] + } + + case class I32C(i: Rep[Num]) extends StagedConcreteNum + case class I64C(i: Rep[Num]) extends StagedConcreteNum + case class F32C(i: Rep[Num]) extends StagedConcreteNum + case class F64C(i: Rep[Num]) extends StagedConcreteNum + + + trait StagedSymbolicNum { + def tipe: ValueType = this match { + case I32S(_) => NumType(I32Type) + case I64S(_) => NumType(I64Type) + case F32S(_) => NumType(F32Type) + case F64S(_) => NumType(F64Type) + } def s: Rep[SymVal] } - case class I32(i: Rep[Num], s: Rep[SymVal]) extends StagedNum - case class I64(i: Rep[Num], s: Rep[SymVal]) extends StagedNum - case class F32(i: Rep[Num], s: Rep[SymVal]) extends StagedNum - case class F64(i: Rep[Num], s: Rep[SymVal]) extends StagedNum - def toStagedNum(num: Num): StagedNum = { + case class I32S(s: Rep[SymVal]) extends StagedSymbolicNum + case class I64S(s: Rep[SymVal]) extends StagedSymbolicNum + case class F32S(s: Rep[SymVal]) extends StagedSymbolicNum + case class F64S(s: Rep[SymVal]) extends StagedSymbolicNum + + def toStagedNum(num: Num): StagedConcreteNum = { num match { - case I32V(_) => I32(num, Concrete(num)) - case I64V(_) => I64(num, Concrete(num)) - case F32V(_) => F32(num, Concrete(num)) - case F64V(_) => F64(num, Concrete(num)) + case I32V(_) => I32C(num) + case I64V(_) => I64C(num) + case F32V(_) => F32C(num) + case F64V(_) => F64C(num) + } + } + + def toStagedSymbolicNum(num: Num): StagedSymbolicNum = { + num match { + case I32V(_) => I32S(Concrete(num)) + case I64V(_) => I64S(Concrete(num)) + case F32V(_) => F32S(Concrete(num)) + case F64V(_) => F64S(Concrete(num)) } } @@ -59,12 +88,21 @@ trait StagedWasmEvaluator extends SAIOps { case NumType(F64Type) => 8 } - def toTagger: (Rep[Num], Rep[SymVal]) => StagedNum = { + def concreteTag: (Rep[Num]) => StagedConcreteNum = { + ty match { + case NumType(I32Type) => I32C + case NumType(I64Type) => I64C + case NumType(F32Type) => F32C + case NumType(F64Type) => F64C + } + } + + def symbolicTag: (Rep[SymVal]) => StagedSymbolicNum = { ty match { - case NumType(I32Type) => I32 - case NumType(I64Type) => I64 - case NumType(F32Type) => F32 - case NumType(F64Type) => F64 + case NumType(I32Type) => I32S + case NumType(I64Type) => I64S + case NumType(F32Type) => F32S + case NumType(F64Type) => F64S } } } @@ -74,12 +112,22 @@ trait StagedWasmEvaluator extends SAIOps { frameTypes: List[ValueType] ) { def push(ty: ValueType): Context = { - Context(ty :: stackTypes, frameTypes) + this.copy(stackTypes = ty :: stackTypes) + } + + def peek: ValueType = { + stackTypes.head } def pop(): (ValueType, Context) = { val (ty :: rest) = stackTypes - (ty, Context(rest, frameTypes)) + (ty, this.copy(stackTypes = rest)) + } + + def take(n: Int): Context = { + Predef.assert(n <= stackTypes.size, s"Context.take size $n is larger than stack size ${stackTypes.size}") + val (taken, rest) = stackTypes.splitAt(n) + this.copy(stackTypes = rest) } def shift(offset: Int, size: Int): Context = { @@ -93,11 +141,50 @@ trait StagedWasmEvaluator extends SAIOps { ) } } + + } + + case class ContextTransition(startCtx: Context, history: List[Instr], endCtx: Context) { + def log(instr: Instr): ContextTransition = { + this.copy(history = instr :: history) + } + + def clearHistory: (Context, List[Instr], CleanCT) = { + (startCtx, history, CleanCT(endCtx)) + } + + def push(ty: ValueType): ContextTransition = { + this.copy(endCtx = endCtx.push(ty)) + } + + def peek: ValueType = { + endCtx.peek + } + + def pop(): (ValueType, ContextTransition) = { + val (ty, newCtx) = endCtx.pop() + (ty, this.copy(endCtx = newCtx)) + } + + def take(n: Int): ContextTransition = { + this.copy(endCtx = endCtx.take(n)) + } + + def shift(offset: Int, size: Int): ContextTransition = { + this.copy(endCtx = endCtx.shift(offset, size)) + } + } + + case class CleanCT(ctx: Context) + + // we can treat every CleanCT as a ContextTransition + implicit def toContextCT(ct: CleanCT): ContextTransition = { + ContextTransition(ct.ctx, Nil, ct.ctx) } type MCont[A] = Unit => A type Cont[A] = (MCont[A]) => A - type Trail[A] = List[Context => Rep[Cont[A]]] + type Trail[A] = List[CleanCT => Rep[Cont[A]]] // a cache storing the compiled code for each function, to reduce re-compilation val compileCache = new HashMap[Int, Rep[(MCont[Unit]) => Unit]] @@ -113,173 +200,268 @@ trait StagedWasmEvaluator extends SAIOps { } + // TODO: maybe we don't need concern snapshot at compile time at all + trait Snapshot + + // Create a snapshot of the symbolic execution, we should ensure that current symstack is in use + // We don't need to store the control information, since the control is totally decided by concrete states + def makeSnapshot(): Rep[Snapshot] = { + "snapshot-make".reflectCtrlWith[Snapshot]() + } + + def isSymStateInUse: Rep[Boolean] = !ReuseManager.isReusing + def eval(insts: List[Instr], - kont: Context => Rep[Cont[Unit]], + kont: CleanCT => Rep[Cont[Unit]], mkont: Rep[MCont[Unit]], trail: Trail[Unit]) - (implicit ctx: Context): Rep[Unit] = { - if (insts.isEmpty) return kont(ctx)(mkont) + (oldCT: ContextTransition): Rep[Unit] = { + if (insts.isEmpty) { + val (oldCtx, history, ct) = oldCT.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + return kont(ct)(mkont) + } // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") // Predef.println(s"[DEBUG] Current context: $ctx") - val (inst, rest) = (insts.head, insts.tail) + val ct = oldCT.log(inst) inst match { case Drop => - val (_, newCtx) = Stack.pop() - eval(rest, kont, mkont, trail)(newCtx) + val (ty, ct1) = ct.pop() + Stack.popC(ty) + eval(rest, kont, mkont, trail)(ct1) case WasmConst(num) => - val newCtx = Stack.push(toStagedNum(num)) - eval(rest, kont, mkont, trail)(newCtx) + Stack.pushC(toStagedNum(num)) + val ct1 = ct.push(num.tipe(module)) + eval(rest, kont, mkont, trail)(ct1) case Symbolic(ty) => - val (id, newCtx1) = Stack.pop() - val symVal = id.makeSymbolic() - val concVal = SymEnv.read(symVal) - val tagger = ty.toTagger - val value = tagger(concVal, symVal) - val newCtx2 = Stack.push(value)(newCtx1) - eval(rest, kont, mkont, trail)(newCtx2) + val id = Stack.popC(ty) + val symVal = id.makeSymbolic(ty) + val num = SymEnv.read(symVal.s) + Stack.pushC(ty.concreteTag(num)) + val ct1 = ct.pop()._2.push(ty) + eval(rest, kont, mkont, trail)(ct1) case LocalGet(i) => - val newCtx = Stack.push(Frames.get(i)) - eval(rest, kont, mkont, trail)(newCtx) + Stack.pushC(Frames.getC(i)(ct.endCtx)) + val ct1 = ct.push(ct.endCtx.frameTypes(i)) + eval(rest, kont, mkont, trail)(ct1) case LocalSet(i) => - val (num, newCtx) = Stack.pop() - Frames.set(i, num)(newCtx) - eval(rest, kont, mkont, trail)(newCtx) + val (ty, ct1) = ct.pop() + val num = Stack.popC(ty) + Frames.setC(i, num) + eval(rest, kont, mkont, trail)(ct1) case LocalTee(i) => - val (num, newCtx) = Stack.peek - Frames.set(i, num) - eval(rest, kont, mkont, trail)(newCtx) + val ty = ct.peek + val num = Stack.peekC(ty) + Frames.setC(i, num) + eval(rest, kont, mkont, trail)(ct) case GlobalGet(i) => - val newCtx = Stack.push(Globals(i)) - eval(rest, kont, mkont, trail)(newCtx) + Stack.pushC(Globals.getC(i)) + val ct1 = ct.push(module.globals(i).ty.ty) + eval(rest, kont, mkont, trail)(ct1) case GlobalSet(i) => - val (value, newCtx) = Stack.pop() + val (ty, ct1) = ct.pop() + val num = Stack.popC(ty) module.globals(i).ty match { - case GlobalType(tipe, true) => Globals(i) = value + case GlobalType(tipe, true) => { + Globals.setC(i, num) + } case _ => throw new Exception("Cannot set immutable global") } - eval(rest, kont, mkont, trail)(newCtx) + eval(rest, kont, mkont, trail)(ct1) case Store(StoreOp(align, offset, ty, None)) => - val (value, newCtx1) = Stack.pop() - val (addr, newCtx2) = Stack.pop()(newCtx1) + val (ty1, ct1) = ct.pop() + val value = Stack.popC(ty1) + val (ty2, ct2) = ct1.pop() + val addr = Stack.popC(ty2) Memory.storeInt(addr.toInt, offset, value.toInt) - eval(rest, kont, mkont, trail)(newCtx2) - case Nop => eval(rest, kont, mkont, trail) + eval(rest, kont, mkont, trail)(ct2) + case Nop => eval(rest, kont, mkont, trail)(ct) case Load(LoadOp(align, offset, ty, None, None)) => - val (addr, newCtx1) = Stack.pop() - val value = Memory.loadInt(addr.toInt, offset) - val newCtx2 = Stack.push(value)(newCtx1) - eval(rest, kont, mkont, trail)(newCtx2) + val (ty1, ct1) = ct.pop() + val addr = Stack.popC(ty1) + val num = Memory.loadIntC(addr.toInt, offset) + Stack.pushC(num) + val ct2 = ct1.push(ty) + eval(rest, kont, mkont, trail)(ct2) case MemorySize => ??? case MemoryGrow => - val (delta, newCtx1) = Stack.pop() + val (ty, ct1) = ct.pop() + val delta = Stack.popC(ty) val ret = Memory.grow(delta.toInt) val retNum = Values.I32V(ret) - val retSym = "Concrete".reflectCtrlWith[SymVal](retNum) - val newCtx2 = Stack.push(I32(retNum, retSym))(newCtx1) - eval(rest, kont, mkont, trail)(newCtx2) + // For now, we assume that the result of memory.grow only depends on the execution path, + // we can relax this by turning it return to a symbol value and mimic the memory.grow's result as input. + Stack.pushC(I32C(retNum)) + val ct2 = ct1.push(NumType(I32Type)) + eval(rest, kont, mkont, trail)(ct2) case MemoryFill => ??? case Unreachable => unreachable() case Test(op) => - val (v, newCtx1) = Stack.pop() - val newCtx2 = Stack.push(evalTestOp(op, v))(newCtx1) - eval(rest, kont, mkont, trail)(newCtx2) + val (ty, ct1) = ct.pop() + val v = Stack.popC(ty) + Stack.pushC(evalTestOpC(op, v)) + val ct2 = ct1.push(v.tipe) + eval(rest, kont, mkont, trail)(ct2) case Unary(op) => - val (v, newCtx1) = Stack.pop() - val newCtx2 = Stack.push(evalUnaryOp(op, v))(newCtx1) - eval(rest, kont, mkont, trail)(newCtx2) + val (ty, ct1) = ct.pop() + val v = Stack.popC(ty) + val res = evalUnaryOpC(op, v) + Stack.pushC(res) + val ct2 = ct1.push(res.tipe) + eval(rest, kont, mkont, trail)(ct2) case Binary(op) => - val (v2, newCtx1) = Stack.pop() - val (v1, newCtx2) = Stack.pop()(newCtx1) - val newCtx3 = Stack.push(evalBinOp(op, v1, v2))(newCtx2) - eval(rest, kont, mkont, trail)(newCtx3) + val (ty2, ct1) = ct.pop() + val v2 = Stack.popC(ty2) + val (ty1, ct2) = ct1.pop() + val v1 = Stack.popC(ty1) + val res = evalBinOpC(op, v1, v2) + Stack.pushC(res) + val ct3 = ct2.push(res.tipe) + eval(rest, kont, mkont, trail)(ct3) case Compare(op) => - val (v2, newCtx1) = Stack.pop() - val (v1, newCtx2) = Stack.pop()(newCtx1) - val newCtx3 = Stack.push(evalRelOp(op, v1, v2))(newCtx2) - eval(rest, kont, mkont, trail)(newCtx3) + val (ty2, ct1) = ct.pop() + val v2 = Stack.popC(ty2) + val (ty1, ct2) = ct1.pop() + val v1 = Stack.popC(ty1) + val res = evalRelOpC(op, v1, v2) + Stack.pushC(res) + val ct3 = ct2.push(res.tipe) + eval(rest, kont, mkont, trail)(ct3) case WasmBlock(ty, inner) => // no need to modify the stack when entering a block // the type system guarantees that we will never take more than the input size from the stack val funcTy = ty.funcType - val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val exitSize = ct.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size val dummy = makeDummy - def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the block, stackSize =", Stack.size) - val offset = restCtx.stackTypes.size - exitSize - val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) - eval(rest, kont, mk, trail)(newRestCtx) + val offset = ct.endCtx.stackTypes.size - exitSize + Stack.shiftC(offset, funcTy.out.size) + if (isSymStateInUse) { + Stack.shiftS(offset, funcTy.out.size) + } + val ct1 = ct.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(ct1) }) - eval(inner, restK _, mkont, restK _ :: trail) + // TODO: extract this into a function + val (oldCtx, history, ct1) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + eval(inner, restK _, mkont, restK _ :: trail)(ct1) case Loop(ty, inner) => val funcTy = ty.funcType - val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val exitSize = ct.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size val dummy = makeDummy - def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the loop, stackSize =", Stack.size) - val offset = restCtx.stackTypes.size - exitSize - val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) - eval(rest, kont, mk, trail)(newRestCtx) + val offset = ct.endCtx.stackTypes.size - exitSize + Stack.shiftC(offset, funcTy.out.size) + if (isSymStateInUse) { + Stack.shiftS(offset, funcTy.out.size) + } + val ct1 = ct.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(ct1) }) - val enterSize = ctx.stackTypes.size - def loop(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + val enterSize = ct.endCtx.stackTypes.size + def loop(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Entered the loop, stackSize =", Stack.size) - val offset = restCtx.stackTypes.size - enterSize - val newRestCtx = Stack.shift(offset, funcTy.inps.size)(restCtx) - eval(inner, restK _, mk, loop _ :: trail)(newRestCtx) + val offset = ct.endCtx.stackTypes.size - enterSize + Stack.shiftC(offset, funcTy.inps.size) + if (isSymStateInUse) { + Stack.shiftS(offset, funcTy.inps.size) + } + val ct1 = ct.shift(offset, funcTy.inps.size) + eval(inner, restK _, mk, loop _ :: trail)(ct1) }) - loop(ctx)(mkont) + val (oldCtx, history, ct1) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + loop(ct1)(mkont) case If(ty, thn, els) => val funcTy = ty.funcType - val (cond, newCtx) = Stack.pop() - val exitSize = newCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size - // TODO: can we avoid code duplication here? - val dummy = makeDummy - def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + val (condTy, ct1) = ct.pop() + val cond = Stack.popC(condTy) + val exitSize = ct1.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size + def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the if, stackSize =", Stack.size) - val offset = restCtx.stackTypes.size - exitSize - val newRestCtx = Stack.shift(offset, funcTy.out.size)(restCtx) - eval(rest, kont, mk, trail)(newRestCtx) + val offset = ct.endCtx.stackTypes.size - exitSize + Stack.shiftC(offset, funcTy.out.size) + if (isSymStateInUse) { + Stack.shiftS(offset, funcTy.out.size) + } + val ct1 = ct.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(ct1) }) - // TODO: put the cond.s to path condition - ExploreTree.fillWithIfElse(cond.s) + val (oldCtx, history, ct2) = ct1.clearHistory + if (isSymStateInUse) { + // when we are not reusing + evalSym(history)(oldCtx) + val snapshot = makeSnapshot() + val symCond = Stack.popS(condTy) + ExploreTree.fillWithIfElse(symCond.s, snapshot) + } if (cond.toInt != 0) { ExploreTree.moveCursor(true) - eval(thn, restK _, mkont, restK _ :: trail)(newCtx) + eval(thn, restK _, mkont, restK _ :: trail)(ct2) } else { ExploreTree.moveCursor(false) - eval(els, restK _, mkont, restK _ :: trail)(newCtx) + eval(els, restK _, mkont, restK _ :: trail)(ct2) } () case Br(label) => info(s"Jump to $label") - trail(label)(ctx)(mkont) + val (oldCtx, history, ct1) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + trail(label)(ct1)(mkont) case BrIf(label) => - val (cond, newCtx) = Stack.pop() + val (ty, ct1) = ct.pop() + val cond = Stack.popC(ty) + val (oldCtx, history, ct2) = ct1.clearHistory info(s"The br_if(${label})'s condition is ", cond.toInt) - // TODO: put the cond.s to path condition - ExploreTree.fillWithIfElse(cond.s) + if (isSymStateInUse) { + evalSym(history)(oldCtx) + val symCond = Stack.popS(ty) + val snapshot = makeSnapshot() + ExploreTree.fillWithIfElse(symCond.s, snapshot) + } if (cond.toInt != 0) { info(s"Jump to $label") ExploreTree.moveCursor(true) - trail(label)(newCtx)(mkont) + trail(label)(ct2)(mkont) } else { info(s"Continue") ExploreTree.moveCursor(false) - eval(rest, kont, mkont, trail)(newCtx) + eval(rest, kont, mkont, trail)(ct2) } () case BrTable(labels, default) => - val (label, newCtx) = Stack.pop() + val (ty, ct1) = ct.pop() + val label = Stack.popC(ty) + val (oldCtx, history, ct2) = ct1.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } def aux(choices: List[Int], idx: Int): Rep[Unit] = { - if (choices.isEmpty) trail(default)(newCtx)(mkont) + if (choices.isEmpty) trail(default)(ct2)(mkont) else { val cond = (label - toStagedNum(I32V(idx))).isZero() - ExploreTree.fillWithIfElse(cond.s) + if (isSymStateInUse) { + val labelSym = Stack.peekS(ty) + val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() + val snapshot = makeSnapshot() + ExploreTree.fillWithIfElse(condSym.s, snapshot) + } if (cond.toInt != 0) { ExploreTree.moveCursor(true) - trail(choices.head)(newCtx)(mkont) + trail(choices.head)(ct2)(mkont) } else { ExploreTree.moveCursor(false) @@ -288,12 +470,142 @@ trait StagedWasmEvaluator extends SAIOps { } } aux(labels, 0) - case Return => trail.last(ctx)(mkont) - case Call(f) => evalCall(rest, kont, mkont, trail, f, false) - case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true) + if (isSymStateInUse) { + Stack.popS(ty) + } + () + case Return => + // return instruction is also stack-polymorphic + val (oldCtx, history, ct2) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + trail.last(ct2)(mkont) + case Call(f) => evalCall(rest, kont, mkont, trail, f, false)(ct) + case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true)(ct) + case _ => + val todo = "todo-op".reflectCtrlWith[Unit]() + eval(rest, kont, mkont, trail)(ct) + } + } + + def replayAndClearHistory(ct: ContextTransition): ContextTransition = { + val (oldCtx, history, ct1) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } + ct1 + } + + // call the symbolic interpreter to evaluate the history that just executed by + // concrete interpreter + def evalSym(history: List[Instr]) + (ctx: Context): Rep[Unit] = { + // val func = topFun((_: Rep[Unit]) => evalS(history.reverse)) + // func(()) + evalS(history.reverse)(ctx) + } + + def evalS(insts: List[Instr]) + (ctx: Context): Rep[Unit] = { + if (insts.isEmpty) return () + + // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") + // Predef.println(s"[DEBUG] Current context: $ctx") + val (inst, rest) = (insts.head, insts.tail) + inst match { + case Drop => + val (ty, newCtx) = ctx.pop() + Stack.popS(ty) + evalS(rest)(newCtx) + case WasmConst(num) => + Stack.pushS(toStagedSymbolicNum(num)) + val newCtx = ctx.push(num.tipe(module)) + evalS(rest)(newCtx) + case Symbolic(ty) => + val id = Stack.popS(ty) + val symVal = id.makeSymbolic(ty) + Stack.pushS(symVal) + val newCtx = ctx.pop()._2.push(ty) + evalS(rest)(newCtx) + case LocalGet(i) => + Stack.pushS(Frames.getS(i)(ctx)) + val newCtx = ctx.push(ctx.frameTypes(i)) + evalS(rest)(newCtx) + case LocalSet(i) => + val (ty, newCtx) = ctx.pop() + val sym = Stack.popS(ty) + Frames.setS(i, sym) + evalS(rest)(newCtx) + case LocalTee(i) => + val ty = ctx.pop()._1 + val sym = Stack.peekS(ty) + Frames.setS(i, sym) + evalS(rest)(ctx) + case GlobalGet(i) => + Stack.pushS(Globals.getS(i)) + val newCtx = ctx.push(module.globals(i).ty.ty) + evalS(rest)(newCtx) + case GlobalSet(i) => + val (ty, newCtx) = ctx.pop() + val sym = Stack.popS(ty) + module.globals(i).ty match { + case GlobalType(tipe, true) => { + Globals.setS(i, sym) + } + case _ => throw new Exception("Cannot set immutable global") + } + evalS(rest)(newCtx) + case Nop => evalS(rest)(ctx) + case Store(StoreOp(align, offset, ty, None)) => ??? + case Load(LoadOp(align, offset, ty, None, None)) => ??? + case MemorySize => ??? + case MemoryGrow => ??? + case MemoryFill => ??? + case Unreachable => unreachable() + case Test(op) => + val (ty, newCtx1) = ctx.pop() + val s = Stack.popS(ty) + Stack.pushS(evalTestOpS(op, s)) + val newCtx2 = newCtx1.push(s.tipe) + evalS(rest)(newCtx2) + case Unary(op) => + val (ty, newCtx1) = ctx.pop() + val s = Stack.popS(ty) + val res = evalUnaryOpS(op, s) + Stack.pushS(res) + val newCtx2 = newCtx1.push(res.tipe) + evalS(rest)(newCtx2) + case Binary(op) => + val (ty2, newCtx1) = ctx.pop() + val s2 = Stack.popS(ty2) + val (ty1, newCtx2) = newCtx1.pop() + val s1 = Stack.popS(ty1) + val res = evalBinOpS(op, s1, s2) + Stack.pushS(res) + val newCtx3 = newCtx2.push(res.tipe) + evalS(rest)(newCtx3) + case Compare(op) => + val (ty2, newCtx1) = ctx.pop() + val s2 = Stack.popS(ty2) + val (ty1, newCtx2) = newCtx1.pop() + val s1 = Stack.popS(ty1) + val res = evalRelOpS(op, s1, s2) + Stack.pushS(res) + val newCtx3 = newCtx2.push(res.tipe) + evalS(rest)(newCtx3) + case WasmBlock(ty, inner) => () + case Loop(ty, inner) => () + case If(ty, thn, els) => () + case Br(label) => () + case BrIf(label) => () + case BrTable(labels, default) => () + case Return => () + case Call(f) => () + case ReturnCall(f) => () case _ => val todo = "todo-op".reflectCtrlWith[Unit]() - eval(rest, kont, mkont, trail) + evalS(rest)(ctx) } } @@ -301,12 +613,16 @@ trait StagedWasmEvaluator extends SAIOps { def evalCall(rest: List[Instr], - kont: Context => Rep[Cont[Unit]], + kont: CleanCT => Rep[Cont[Unit]], mkont: Rep[MCont[Unit]], trail: Trail[Unit], funcIndex: Int, isTail: Boolean) - (implicit ctx: Context): Rep[Unit] = { + (implicit ct: ContextTransition): Rep[Unit] = { + val (oldCtx, history, ct1) = ct.clearHistory + if (isSymStateInUse) { + evalSym(history)(oldCtx) + } module.funcs(funcIndex) match { case FuncDef(_, FuncBodyDef(ty, _, bodyLocals, body)) => val locals = bodyLocals ++ ty.inps @@ -316,63 +632,102 @@ trait StagedWasmEvaluator extends SAIOps { } else { val callee = topFun((mk: Rep[MCont[Unit]]) => { info(s"Entered the function at $funcIndex, stackSize =", Stack.size) - // we can do some check here to ensure the function returns correct size of stack - eval(body, (_: Context) => forwardKont, mk, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) + // the return instruction is also stack polymorphic + def retK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Exiting the function at $funcIndex, stackSize =", Stack.size) + val offset = ct.ctx.stackTypes.size - ty.out.size + Stack.shiftC(offset, ty.out.size) + Stack.shiftS(offset, ty.out.size) + mk(()) + }) + eval(body, retK _, mk, retK _::Nil)(CleanCT(Context(Nil, locals))) }) compileCache(funcIndex) = callee callee } // Predef.println(s"[DEBUG] locals size: ${locals.size}") - val (args, newCtx) = Stack.take(ty.inps.size) + val ct2 = ct1.take(ty.inps.size) + val exitSize = ty.out.size + ct2.endCtx.stackTypes.size if (isTail) { // when tail call, return to the caller's return continuation - Frames.popFrame(ctx.frameTypes.size) - Frames.pushFrame(locals) - Frames.putAll(args) + val argsC = Stack.takeC(ty.inps) + Frames.popFrameC(ct2.endCtx.frameTypes.size) + Frames.pushFrameC(locals) + Frames.putAllC(argsC) + if (isSymStateInUse) { + val argsS = Stack.takeS(ty.inps) + Frames.popFrameS(ct2.endCtx.frameTypes.size) + Frames.pushFrameS(locals) + Frames.putAllS(argsS) + } callee(mkont) } else { // We make a new trail by `restK`, since function creates a new block to escape // (more or less like `return`) val restK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the function at $funcIndex, stackSize =", Stack.size) - Frames.popFrame(locals.size) - eval(rest, kont, mk, trail)(newCtx.copy(stackTypes = ty.out.reverse ++ ctx.stackTypes.drop(ty.inps.size))) + Frames.popFrameC(locals.size) + Frames.popFrameS(locals.size) + val newCtx = ct2.endCtx.copy(stackTypes = ty.out.reverse ++ ct2.endCtx.stackTypes) + eval(rest, kont, mk, trail)(CleanCT(newCtx)) }) val dummy = makeDummy val newMKont: Rep[MCont[Unit]] = funHere((_u: Rep[Unit]) => { restK(mkont) }, dummy) - Frames.pushFrame(locals) - Frames.putAll(args) + val argsC = Stack.takeC(ty.inps) + Frames.pushFrameC(locals) + Frames.putAllC(argsC) + if (isSymStateInUse) { + val argsS = Stack.takeS(ty.inps) + Frames.pushFrameS(locals) + Frames.putAllS(argsS) + } callee(newMKont) } case Import("console", "log", _) | Import("spectest", "print_i32", _) => //println(s"[DEBUG] current stack: $stack") - val (v, newCtx) = Stack.pop() + val (ty, ct2) = ct1.pop() + val v = Stack.popC(ty) + Stack.popS(ty) println(v.toInt) - eval(rest, kont, mkont, trail)(newCtx) + eval(rest, kont, mkont, trail)(ct2) case Import("console", "assert", _) => - val (v, newCtx) = Stack.pop() + val (ty, ct2) = ct1.pop() + val v = Stack.popC(ty) + // TODO: We should also add s into exploration tree + val s = Stack.popS(ty) runtimeAssert(v.toInt != 0) - eval(rest, kont, mkont, trail)(newCtx) + eval(rest, kont, mkont, trail)(ct2) case Import(_, _, _) => throw new Exception(s"Unknown import at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") } } - def evalTestOp(op: TestOp, value: StagedNum): StagedNum = op match { + def evalTestOpC(op: TestOp, value: StagedConcreteNum): StagedConcreteNum = op match { case Eqz(_) => value.isZero } - def evalUnaryOp(op: UnaryOp, value: StagedNum): StagedNum = op match { + def evalTestOpS(op: TestOp, value: StagedSymbolicNum): StagedSymbolicNum = op match { + case Eqz(_) => value.isZero + } + + def evalUnaryOpC(op: UnaryOp, value: StagedConcreteNum): StagedConcreteNum = op match { case Clz(_) => value.clz() case Ctz(_) => value.ctz() case Popcnt(_) => value.popcnt() case _ => ??? } - def evalBinOp(op: BinOp, v1: StagedNum, v2: StagedNum): StagedNum = op match { + def evalUnaryOpS(op: UnaryOp, value: StagedSymbolicNum): StagedSymbolicNum = op match { + case Clz(_) => value.clz() + case Ctz(_) => value.ctz() + case Popcnt(_) => value.popcnt() + case _ => ??? + } + + def evalBinOpC(op: BinOp, v1: StagedConcreteNum, v2: StagedConcreteNum): StagedConcreteNum = op match { case Add(_) => v1 + v2 case Mul(_) => v1 * v2 case Sub(_) => v1 - v2 @@ -386,7 +741,35 @@ trait StagedWasmEvaluator extends SAIOps { throw new Exception(s"Unknown binary operation $op") } - def evalRelOp(op: RelOp, v1: StagedNum, v2: StagedNum): StagedNum = op match { + def evalBinOpS(op: BinOp, v1: StagedSymbolicNum, v2: StagedSymbolicNum): StagedSymbolicNum = op match { + case Add(_) => v1 + v2 + case Mul(_) => v1 * v2 + case Sub(_) => v1 - v2 + case Shl(_) => v1 << v2 + // case ShrS(_) => v1 >> v2 // TODO: signed shift right + case ShrU(_) => v1 >> v2 + case And(_) => v1 & v2 + case DivS(_) => v1 / v2 + case DivU(_) => v1 / v2 + case _ => + throw new Exception(s"Unknown binary operation $op") + } + + def evalRelOpC(op: RelOp, v1: StagedConcreteNum, v2: StagedConcreteNum): StagedConcreteNum = op match { + case Eq(_) => v1 numEq v2 + case Ne(_) => v1 numNe v2 + case LtS(_) => v1 < v2 + case LtU(_) => v1 ltu v2 + case GtS(_) => v1 > v2 + case GtU(_) => v1 gtu v2 + case LeS(_) => v1 <= v2 + case LeU(_) => v1 leu v2 + case GeS(_) => v1 >= v2 + case GeU(_) => v1 geu v2 + case _ => ??? + } + + def evalRelOpS(op: RelOp, v1: StagedSymbolicNum, v2: StagedSymbolicNum): StagedSymbolicNum = op match { case Eq(_) => v1 numEq v2 case Ne(_) => v1 numNe v2 case LtS(_) => v1 < v2 @@ -426,12 +809,14 @@ trait StagedWasmEvaluator extends SAIOps { } val (instrs, locals) = (funBody.body, funBody.locals) resetStacks() - Frames.pushFrame(locals) - eval(instrs, (_: Context) => forwardKont, mkont, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) - Frames.popFrame(locals.size) + Frames.pushFrameC(locals) + Frames.pushFrameS(locals) + eval(instrs, _ => forwardKont, mkont, ((_: CleanCT) => forwardKont)::Nil)(CleanCT(Context(Nil, locals))) + Frames.popFrameC(locals.size) + Frames.popFrameS(locals.size) } - def evalTop(main: Option[String], printRes: Boolean, dumpTree: Option[String]): Rep[Unit] = { + def evalTop(main: Option[String], printRes: Boolean): Rep[Unit] = { val haltK: Rep[Unit] => Rep[Unit] = (_) => { info("Exiting the program...") if (printRes) { @@ -450,66 +835,78 @@ trait StagedWasmEvaluator extends SAIOps { // stack operations object Stack { - def shift(offset: Int, size: Int)(ctx: Context): Context = { + def shiftC(offset: Int, size: Int) = { if (offset > 0) { "stack-shift".reflectCtrlWith[Unit](offset, size) } - ctx.shift(offset, size) + } + + def shiftS(offset: Int, size: Int) = { + if (offset > 0) { + "sym-stack-shift".reflectCtrlWith[Unit](offset, size) + } } def initialize(): Rep[Unit] = { "stack-init".reflectCtrlWith[Unit]() } - def pop()(implicit ctx: Context): (StagedNum, Context) = { - val (ty, newContext) = ctx.pop() - val num = ty match { - case NumType(I32Type) => I32("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(I64Type) => I64("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F32("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F64("stack-pop".reflectCtrlWith[Num](), "sym-stack-pop".reflectCtrlWith[SymVal]()) - } - (num, newContext) + def popC(ty: ValueType): StagedConcreteNum = ty match { + case NumType(I32Type) => I32C("stack-pop".reflectCtrlWith[Num]()) + case NumType(I64Type) => I64C("stack-pop".reflectCtrlWith[Num]()) + case NumType(F32Type) => F32C("stack-pop".reflectCtrlWith[Num]()) + case NumType(F32Type) => F64C("stack-pop".reflectCtrlWith[Num]()) } - def peek(implicit ctx: Context): (StagedNum, Context) = { - val ty = ctx.stackTypes.head - val num = ty match { - case NumType(I32Type) => I32("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(I64Type) => I64("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F32("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F64("stack-peek".reflectCtrlWith[Num](), "sym-stack-peek".reflectCtrlWith[SymVal]()) - } - (num, ctx) + def popS(ty: ValueType): StagedSymbolicNum = ty match { + case NumType(I32Type) => I32S("sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(I64Type) => I64S("sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F32S("sym-stack-pop".reflectCtrlWith[SymVal]()) + case NumType(F64Type) => F64S("sym-stack-pop".reflectCtrlWith[SymVal]()) } - def push(num: StagedNum)(implicit ctx: Context): Context = { - num match { - case I32(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) - case I64(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) - case F32(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) - case F64(v, s) => "stack-push".reflectCtrlWith[Unit](v); "sym-stack-push".reflectCtrlWith[Unit](s) - } - ctx.push(num.tipe) + def peekC(ty: ValueType): StagedConcreteNum = ty match { + case NumType(I32Type) => I32C("stack-peek".reflectCtrlWith[Num]()) + case NumType(I64Type) => I64C("stack-peek".reflectCtrlWith[Num]()) + case NumType(F32Type) => F32C("stack-peek".reflectCtrlWith[Num]()) + case NumType(F32Type) => F64C("stack-peek".reflectCtrlWith[Num]()) } - def take(n: Int)(implicit ctx: Context): (List[StagedNum], Context) = n match { - case 0 => (Nil, ctx) - case n => - val (v, newCtx1) = pop() - val (rest, newCtx2) = take(n - 1) - (v::rest, newCtx2) + def peekS(ty: ValueType): StagedSymbolicNum = ty match { + case NumType(I32Type) => I32S("sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(I64Type) => I64S("sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(F32Type) => F32S("sym-stack-peek".reflectCtrlWith[SymVal]()) + case NumType(F64Type) => F64S("sym-stack-peek".reflectCtrlWith[SymVal]()) } - def drop(n: Int)(implicit ctx: Context): Context = { - take(n)._2 + def pushC(num: StagedConcreteNum) = num match { + case I32C(v) => "stack-push".reflectCtrlWith[Unit](v) + case I64C(v) => "stack-push".reflectCtrlWith[Unit](v) + case F32C(v) => "stack-push".reflectCtrlWith[Unit](v) + case F64C(v) => "stack-push".reflectCtrlWith[Unit](v) } - def shift(offset: Rep[Int], size: Rep[Int]): Rep[Unit] = { - if (offset > 0) { - "stack-shift".reflectCtrlWith[Unit](offset, size) - "sym-stack-shift".reflectCtrlWith[Unit](offset, size) - } + def pushS(num: StagedSymbolicNum) = num match { + case I32S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) + case I64S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) + case F32S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) + case F64S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) + } + + def takeC(types: List[ValueType]): List[StagedConcreteNum] = types match { + case Nil => Nil + case t :: ts => + val v = popC(t) + val rest = takeC(ts) + v :: rest + } + + def takeS(types: List[ValueType]): List[StagedSymbolicNum] = types match { + case Nil => Nil + case t :: ts => + val v = popS(t) + val rest = takeS(ts) + v :: rest } def print(): Rep[Unit] = { @@ -522,41 +919,72 @@ trait StagedWasmEvaluator extends SAIOps { } object Frames { - def get(i: Int)(implicit ctx: Context): StagedNum = { + def getC(i: Int)(implicit ctx: Context): StagedConcreteNum = { // val offset = ctx.frameTypes.take(i).map(_.size).sum ctx.frameTypes(i) match { - case NumType(I32Type) => I32("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(I64Type) => I64("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(F32Type) => F32("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(F64Type) => F64("frame-get".reflectCtrlWith[Num](i), "sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(I32Type) => I32C("frame-get".reflectCtrlWith[Num](i)) + case NumType(I64Type) => I64C("frame-get".reflectCtrlWith[Num](i)) + case NumType(F32Type) => F32C("frame-get".reflectCtrlWith[Num](i)) + case NumType(F64Type) => F64C("frame-get".reflectCtrlWith[Num](i)) } } - def set(i: Int, v: StagedNum)(implicit ctx: Context): Rep[Unit] = { - // val offset = ctx.frameTypes.take(i).map(_.size).sum + def getS(i: Int)(implicit ctx: Context): StagedSymbolicNum = { + ctx.frameTypes(i) match { + case NumType(I32Type) => I32S("sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(I64Type) => I64S("sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(F32Type) => F32S("sym-frame-get".reflectCtrlWith[SymVal](i)) + case NumType(F64Type) => F64S("sym-frame-get".reflectCtrlWith[SymVal](i)) + } + } + + def setC(i: Int, v: StagedConcreteNum): Rep[Unit] = { v match { - case I32(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) - case I64(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) - case F32(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) - case F64(v, s) => "frame-set".reflectCtrlWith[Unit](i, v); "sym-frame-set".reflectCtrlWith[Unit](i, s) + case I32C(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case I64C(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case F32C(v) => "frame-set".reflectCtrlWith[Unit](i, v) + case F64C(v) => "frame-set".reflectCtrlWith[Unit](i, v) + } + } + + def setS(i: Int, s: StagedSymbolicNum): Rep[Unit] = { + s match { + case I32S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) + case I64S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) + case F32S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) + case F64S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) } } - def pushFrame(locals: List[ValueType]): Rep[Unit] = { + def pushFrameC(locals: List[ValueType]): Rep[Unit] = { // Predef.println(s"[DEBUG] push frame: $locals") val size = locals.size "frame-push".reflectCtrlWith[Unit](size) + } + + def pushFrameS(locals: List[ValueType]): Rep[Unit] = { + // Predef.println(s"[DEBUG] push frame: $locals") + val size = locals.size "sym-frame-push".reflectCtrlWith[Unit](size) } - def popFrame(size: Int): Rep[Unit] = { + def popFrameC(size: Int): Rep[Unit] = { "frame-pop".reflectCtrlWith[Unit](size) + } + + def popFrameS(size: Int): Rep[Unit] = { "sym-frame-pop".reflectCtrlWith[Unit](size) } - def putAll(args: List[StagedNum])(implicit ctx: Context): Rep[Unit] = { + def putAllC(args: List[StagedConcreteNum]): Rep[Unit] = { for ((arg, i) <- args.view.reverse.zipWithIndex) { - Frames.set(i, arg) + Frames.setC(i, arg) + } + } + + def putAllS(args: List[StagedSymbolicNum]): Rep[Unit] = { + for ((arg, i) <- args.view.reverse.zipWithIndex) { + Frames.setS(i, arg) } } } @@ -567,8 +995,12 @@ trait StagedWasmEvaluator extends SAIOps { // todo: store symbolic value to memory via extract/concat operation } - def loadInt(base: Rep[Int], offset: Int): StagedNum = { - I32("I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset)), "sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) + def loadIntC(base: Rep[Int], offset: Int): StagedConcreteNum = { + I32C("I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset))) + } + + def loadIntS(base: Rep[Int], offset: Int): StagedSymbolicNum = { + I32S("sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) } // Returns the previous memory size on success, or -1 if the memory cannot be grown. @@ -603,29 +1035,47 @@ trait StagedWasmEvaluator extends SAIOps { // global read/write object Globals { - def apply(i: Int): StagedNum = { + def getC(i: Int): StagedConcreteNum = { module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => I32("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(I64Type), _) => I64("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(F32Type), _) => F32("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(F64Type), _) => F64("global-get".reflectCtrlWith[Num](i), "sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(I32Type), _) => I32C("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(I64Type), _) => I64C("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(F32Type), _) => F32C("global-get".reflectCtrlWith[Num](i)) + case GlobalType(NumType(F64Type), _) => F64C("global-get".reflectCtrlWith[Num](i)) } } - def update(i: Int, v: StagedNum): Rep[Unit] = { + def getS(i: Int): StagedSymbolicNum = { module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) - case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) - case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) - case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i);"sym-global-set".reflectCtrlWith[Unit](i, v.s) + case GlobalType(NumType(I32Type), _) => I32S("sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(I64Type), _) => I64S("sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(F32Type), _) => F32S("sym-global-get".reflectCtrlWith[SymVal](i)) + case GlobalType(NumType(F64Type), _) => F64S("sym-global-get".reflectCtrlWith[SymVal](i)) + } + } + + def setC(i: Int, v: StagedConcreteNum): Rep[Unit] = { + module.globals(i).ty match { + case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) + case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) + case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) + case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) + } + } + + def setS(i: Int, s: StagedSymbolicNum): Rep[Unit] = { + module.globals(i).ty match { + case GlobalType(NumType(I32Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) + case GlobalType(NumType(I64Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) + case GlobalType(NumType(F32Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) + case GlobalType(NumType(F64Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) } } } // Exploration tree, object ExploreTree { - def fillWithIfElse(s: Rep[SymVal]): Rep[Unit] = { - "tree-fill-if-else".reflectCtrlWith[Unit](s) + def fillWithIfElse(sym: Rep[SymVal], snapshot: Rep[Snapshot]): Rep[Unit] = { + "tree-fill-if-else".reflectCtrlWith[Unit](sym, snapshot) } def fillWithFinished(): Rep[Unit] = { @@ -633,6 +1083,7 @@ trait StagedWasmEvaluator extends SAIOps { } def moveCursor(branch: Boolean): Rep[Unit] = { + // when moving cursor from to an unexplored node, we need to change the reuse state "tree-move-cursor".reflectCtrlWith[Unit](branch) } @@ -651,165 +1102,337 @@ trait StagedWasmEvaluator extends SAIOps { } } + object ReuseManager { + def isReusing: Rep[Boolean] = { + "reuse-is-reusing".reflectCtrlWith[Boolean]() + } + + def turnOnReuse(): Rep[Unit] = { + "reuse-turn-on".reflectCtrlWith[Unit]() + } + + def turnOffReuse(): Rep[Unit] = { + "reuse-turn-off".reflectCtrlWith[Unit]() + } + } + // runtime Num type - implicit class StagedNumOps(num: StagedNum) { + implicit class StagedConcreteNumOps(num: StagedConcreteNum) { + + def makeSymbolic(ty: ValueType): StagedSymbolicNum = num match { + case I32C(x) => I32S("make-symbolic-concrete".reflectCtrlWith[SymVal](num.toInt)) + } def toInt: Rep[Int] = "num-to-int".reflectCtrlWith[Int](num.i) - def isZero(): StagedNum = num match { - case I32(x_c, x_s) => I32(Values.I32V("is-zero".reflectCtrlWith[Int](num.toInt)), "sym-is-zero".reflectCtrlWith[SymVal](x_s)) + def isZero(): StagedConcreteNum = num match { + case I32C(x_c) => I32C(Values.I32V("is-zero".reflectCtrlWith[Int](num.toInt))) + } + + def clz(): StagedConcreteNum = num match { + case I32C(x) => I32C("clz".reflectCtrlWith[Num](x)) + case I64C(x) => I64C("clz".reflectCtrlWith[Num](x)) + } + + def ctz(): StagedConcreteNum = num match { + case I32C(x) => I32C("ctz".reflectCtrlWith[Num](x)) + case I64C(x) => I64C("ctz".reflectCtrlWith[Num](x)) + } + + def popcnt(): StagedConcreteNum = num match { + case I32C(x) => I32C("popcnt".reflectCtrlWith[Num](x)) + case I64C(x) => I64C("popcnt".reflectCtrlWith[Num](x)) + } + + def +(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-add".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-add".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-add".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-add".reflectCtrlWith[Num](x, y)) + } + } + + def -(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-sub".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-sub".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-sub".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-sub".reflectCtrlWith[Num](x, y)) + } + } + + def *(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-mul".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-mul".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-mul".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-mul".reflectCtrlWith[Num](x, y)) + } + } + + def /(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-div".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-div".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-div".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-div".reflectCtrlWith[Num](x, y)) + } + } + + def <<(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-shl".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-shl".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-shl".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-shl".reflectCtrlWith[Num](x, y)) + } + } + + def >>(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-shr".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-shr".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-shr".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-shr".reflectCtrlWith[Num](x, y)) + } + } + + def &(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("binary-and".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I64C("binary-and".reflectCtrlWith[Num](x, y)) + case (F32C(x), F32C(y)) => F32C("binary-and".reflectCtrlWith[Num](x, y)) + case (F64C(x), F64C(y)) => F64C("binary-and".reflectCtrlWith[Num](x, y)) + } + } + + def numEq(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-eq".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-eq".reflectCtrlWith[Num](x, y)) + } + } + + def numNe(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-ne".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-ne".reflectCtrlWith[Num](x, y)) + } + } + + def <(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-lt".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-lt".reflectCtrlWith[Num](x, y)) + } } - def clz(): StagedNum = num match { - case I32(x_c, x_s) => I32("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) - case I64(x_c, x_s) => I64("clz".reflectCtrlWith[Num](x_c), "sym-clz".reflectCtrlWith[SymVal](x_s)) + def ltu(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-ltu".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-ltu".reflectCtrlWith[Num](x, y)) + } } - def ctz(): StagedNum = num match { - case I32(x_c, x_s) => I32("ctz".reflectCtrlWith[Num](x_c), "sym-ctz".reflectCtrlWith[SymVal](x_s)) - case I64(x_c, x_s) => I64("ctz".reflectCtrlWith[Num](x_c), "sym-ctz".reflectCtrlWith[SymVal](x_s)) + def >(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-gt".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-gt".reflectCtrlWith[Num](x, y)) + } } - def popcnt(): StagedNum = num match { - case I32(x_c, x_s) => I32("popcnt".reflectCtrlWith[Num](x_c), "sym-popcnt".reflectCtrlWith[SymVal](x_s)) - case I64(x_c, x_s) => I64("popcnt".reflectCtrlWith[Num](x_c), "sym-popcnt".reflectCtrlWith[SymVal](x_s)) + def gtu(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-gtu".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-gtu".reflectCtrlWith[Num](x, y)) + } } - def makeSymbolic(): Rep[SymVal] = { - "make-symbolic".reflectCtrlWith[SymVal](num.s) + def <=(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-le".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-le".reflectCtrlWith[Num](x, y)) + } + } + + def leu(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-leu".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-leu".reflectCtrlWith[Num](x, y)) + } } - def +(rhs: StagedNum): StagedNum = { + def >=(rhs: StagedConcreteNum): StagedConcreteNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-add".reflectCtrlWith[Num](x_c, y_c), "sym-binary-add".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32C(x), I32C(y)) => I32C("relation-ge".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-ge".reflectCtrlWith[Num](x, y)) } } + def geu(rhs: StagedConcreteNum): StagedConcreteNum = { + (num, rhs) match { + case (I32C(x), I32C(y)) => I32C("relation-geu".reflectCtrlWith[Num](x, y)) + case (I64C(x), I64C(y)) => I32C("relation-geu".reflectCtrlWith[Num](x, y)) + } + } + } + + implicit class StagedSymbolicNumOps(num: StagedSymbolicNum) { + def makeSymbolic(ty: ValueType): StagedSymbolicNum = num match { + case I32S(x) => I32S("make-symbolic".reflectCtrlWith[SymVal](x)) + case _ => throw new RuntimeException("Symbol index must be an i32") + } + + def isZero(): StagedSymbolicNum = num match { + case I32S(x) => I32S("sym-is-zero".reflectCtrlWith[SymVal](x)) + } + + def clz(): StagedSymbolicNum = num match { + case I32S(x) => I32S("sym-clz".reflectCtrlWith[SymVal](x)) + case I64S(x) => I64S("sym-clz".reflectCtrlWith[SymVal](x)) + } + + def ctz(): StagedSymbolicNum = num match { + case I32S(x) => I32S("sym-ctz".reflectCtrlWith[SymVal](x)) + case I64S(x) => I64S("sym-ctz".reflectCtrlWith[SymVal](x)) + } + + def popcnt(): StagedSymbolicNum = num match { + case I32S(x) => I32S("sym-popcnt".reflectCtrlWith[SymVal](x)) + case I64S(x) => I64S("sym-popcnt".reflectCtrlWith[SymVal](x)) + } + + def +(rhs: StagedSymbolicNum): StagedSymbolicNum = { + (num, rhs) match { + case (I32S(x), I32S(y)) => I32S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) + } + } - def -(rhs: StagedNum): StagedNum = { + def -(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-sub".reflectCtrlWith[Num](x_c, y_c), "sym-binary-sub".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) } } - def *(rhs: StagedNum): StagedNum = { + def *(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-mul".reflectCtrlWith[Num](x_c, y_c), "sym-binary-mul".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) } } - def /(rhs: StagedNum): StagedNum = { + def /(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-div".reflectCtrlWith[Num](x_c, y_c), "sym-binary-div".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) } } - def <<(rhs: StagedNum): StagedNum = { + def <<(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-shl".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shl".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) } } - def >>(rhs: StagedNum): StagedNum = { + def >>(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-shr".reflectCtrlWith[Num](x_c, y_c), "sym-binary-shr".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) } } - def &(rhs: StagedNum): StagedNum = { + def &(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I64("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) - case (F32(x_c, x_s), F32(y_c, y_s)) => F32("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) - case (F64(x_c, x_s), F64(y_c, y_s)) => F64("binary-and".reflectCtrlWith[Num](x_c, y_c), "sym-binary-and".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I64S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) + case (F32S(x), F32S(y)) => F32S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) + case (F64S(x), F64S(y)) => F64S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) } } - def numEq(rhs: StagedNum): StagedNum = { + def numEq(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-eq".reflectCtrlWith[Num](x_c, y_c), "sym-relation-eq".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-eq".reflectCtrlWith[Num](x_c, y_c), "sym-relation-eq".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-eq".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-eq".reflectCtrlWith[SymVal](x, y)) } } - def numNe(rhs: StagedNum): StagedNum = { + def numNe(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ne".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ne".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ne".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ne".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-ne".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-ne".reflectCtrlWith[SymVal](x, y)) } } - def <(rhs: StagedNum): StagedNum = { + def <(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-lt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-lt".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-lt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-lt".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-lt".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-lt".reflectCtrlWith[SymVal](x, y)) } } - def ltu(rhs: StagedNum): StagedNum = { + def ltu(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ltu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ltu".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ltu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ltu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("relation-ltu".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("relation-ltu".reflectCtrlWith[SymVal](x, y)) } } - def >(rhs: StagedNum): StagedNum = { + def >(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-gt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gt".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-gt".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gt".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-gt".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-gt".reflectCtrlWith[SymVal](x, y)) } } - def gtu(rhs: StagedNum): StagedNum = { + def gtu(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-gtu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gtu".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-gtu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-gtu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-gtu".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-gtu".reflectCtrlWith[SymVal](x, y)) } } - def <=(rhs: StagedNum): StagedNum = { + def <=(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-le".reflectCtrlWith[Num](x_c, y_c), "sym-relation-le".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-le".reflectCtrlWith[Num](x_c, y_c), "sym-relation-le".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-le".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-le".reflectCtrlWith[SymVal](x, y)) } } - def leu(rhs: StagedNum): StagedNum = { + def leu(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-leu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-leu".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-leu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-leu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-leu".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-leu".reflectCtrlWith[SymVal](x, y)) } } - def >=(rhs: StagedNum): StagedNum = { + def >=(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-ge".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ge".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-ge".reflectCtrlWith[Num](x_c, y_c), "sym-relation-ge".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-ge".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-ge".reflectCtrlWith[SymVal](x, y)) } } - def geu(rhs: StagedNum): StagedNum = { + def geu(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num, rhs) match { - case (I32(x_c, x_s), I32(y_c, y_s)) => I32("relation-geu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-geu".reflectCtrlWith[SymVal](x_s, y_s)) - case (I64(x_c, x_s), I64(y_c, y_s)) => I32("relation-geu".reflectCtrlWith[Num](x_c, y_c), "sym-relation-geu".reflectCtrlWith[SymVal](x_s, y_s)) + case (I32S(x), I32S(y)) => I32S("sym-relation-geu".reflectCtrlWith[SymVal](x, y)) + case (I64S(x), I64S(y)) => I32S("sym-relation-geu".reflectCtrlWith[SymVal](x, y)) } } } @@ -848,7 +1471,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { else if (m.toString.endsWith("I32V")) "I32V" else if (m.toString.endsWith("I64V")) "I64V" else if (m.toString.endsWith("SymVal")) "SymVal" - + else if (m.toString.endsWith("Snapshot")) "Snapshot_t" else super.remap(m) } @@ -902,10 +1525,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.push("); shallow(value); emit(")") case Node(_, "stack-shift", List(offset, size), _) => emit("Stack.shift("); shallow(offset); emit(", "); shallow(size); emit(")") + case Node(_, "sym-stack-shift", List(offset, size), _) => + emit("SymStack.shift("); shallow(offset); emit(", "); shallow(size); emit(")") case Node(_, "stack-pop", _, _) => emit("Stack.pop()") case Node(_, "sym-stack-pop", _, _) => emit("SymStack.pop()") + case Node(_, "snapshot-make", _, _) => + emit("Snapshot_t()") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(")") case Node(_, "sym-frame-pop", List(i), _) => @@ -935,7 +1562,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "binary-add", List(lhs, rhs), _) => shallow(lhs); emit(" + "); shallow(rhs) case Node(_, "binary-sub", List(lhs, rhs), _) => - shallow(lhs); emit(" - "); shallow(rhs) + // todo: avoid using c++ operator, use explicit method call so operator's precedence issues won't exist + emit("("); shallow(lhs); emit(" - "); shallow(rhs); emit(")") case Node(_, "binary-mul", List(lhs, rhs), _) => shallow(lhs); emit(" * "); shallow(rhs) case Node(_, "binary-div", List(lhs, rhs), _) => @@ -990,12 +1618,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(num); emit(".toInt()") case Node(_, "make-symbolic", List(num), _) => shallow(num); emit(".makeSymbolic()") + case Node(_, "make-symbolic-concrete", List(num), _) => + emit("make_symbolic("); shallow(num); emit(")") case Node(_, "sym-env-read", List(sym), _) => emit("SymEnv.read("); shallow(sym); emit(")") case Node(_, "assert-true", List(cond), _) => emit("GENSYM_ASSERT("); shallow(cond); emit(")") - case Node(_, "tree-fill-if-else", List(s), _) => - emit("ExploreTree.fillIfElseNode("); shallow(s); emit(")") + case Node(_, "tree-fill-if-else", List(sym, snapshot), _) => + emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(", "); shallow(snapshot); emit(")") case Node(_, "tree-fill-finished", List(), _) => emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b), _) => @@ -1006,6 +1636,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.dump_graphviz("); shallow(f); emit(")") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") + case Node(_, "reuse-is-reusing", List(), _) => + emit("Reuse.is_reusing()") case Node(_, "dummy", _, _) => emit("std::monostate()") case Node(_, "dummy-op", _, _) => emit("std::monostate()") case Node(_, "no-op", _, _) => @@ -1063,12 +1695,12 @@ trait WasmToCppCompilerDriver[A, B] extends CppSAIDriver[A, B] with StagedWasmEv object WasmToCppCompiler { case class GeneratedCpp(source: String, headerFolders: List[String]) - def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean, dumpTree: Option[String]): GeneratedCpp = { + def compile(moduleInst: ModuleInstance, main: Option[String], printRes: Boolean): GeneratedCpp = { println(s"Now compiling wasm module with entry function $main") val driver = new WasmToCppCompilerDriver[Unit, Unit] { def module: ModuleInstance = moduleInst def snippet(x: Rep[Unit]): Rep[Unit] = { - evalTop(main, printRes, dumpTree) + evalTop(main, printRes) } } GeneratedCpp(driver.code, driver.codegen.includePaths.toList) @@ -1079,8 +1711,8 @@ object WasmToCppCompiler { outputCpp: String, outputExe: String, printRes: Boolean, - dumpTree: Option[String]): Unit = { - val generated = compile(moduleInst, main, printRes, dumpTree) + macros: String*): Unit = { + val generated = compile(moduleInst, main, printRes) val code = generated.source val writer = new java.io.PrintWriter(new java.io.File(outputCpp)) @@ -1091,7 +1723,9 @@ object WasmToCppCompiler { } import sys.process._ - val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g -l z3 " + generated.headerFolders.map(f => s"-I$f").mkString(" ") + val includeFlags = generated.headerFolders.map(f => s"-I$f").mkString(" ") + val macroFlags = macros.map(m => s"-D$m").mkString(" ") + val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g -l z3 " + includeFlags + " " + macroFlags if (command.! != 0) { throw new RuntimeException(s"Compilation failed for $outputCpp") } diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index a65d0eda..48c24634 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -9,12 +9,24 @@ import gensym.wasm.parser._ import gensym.wasm.stagedconcolicminiwasm._ class TestStagedConcolicEval extends FunSuite { - def testFileToCpp(filename: String, main: Option[String] = None, expect: Option[List[Float]]=None) = { + def testFileConcolicCpp(filename: String, main: Option[String] = None) = { val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" val exe = s"$cppFile.exe" val exploreTreeFile = s"$filename.tree.dot" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, Some(exploreTreeFile)) + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true) + + import sys.process._ + val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! + println(result) + } + + // only test concrete execution and its result + def testFileConcreteCpp(filename: String, main: Option[String] = None, expect: Option[List[Float]] = None) = { + val moduleInst = ModuleInstance(Parser.parseFile(filename)) + val cppFile = s"$filename.cpp" + val exe = s"$cppFile.exe" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, "NO_INFO", "RUN_ONCE") import sys.process._ val result = s"./$exe".!! @@ -30,13 +42,61 @@ class TestStagedConcolicEval extends FunSuite { }) } - test("ack-cpp") { testFileToCpp("./benchmarks/wasm/ack.wat", Some("real_main")) } + test("ack-cpp") { testFileConcolicCpp("./benchmarks/wasm/ack.wat", Some("real_main")) } test("bug-finding") { - testFileToCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) + testFileConcolicCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) } test("brtable-bug-finding") { - testFileToCpp("./benchmarks/wasm/staged/brtable_concolic.wat") + testFileConcolicCpp("./benchmarks/wasm/staged/brtable_concolic.wat") + } + + test("return-poly - concrete") { + testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) + } + test("ack-cpp - concrete") { testFileConcreteCpp("./benchmarks/wasm/ack.wat", Some("real_main"), expect=Some(List(7))) } + test("power - concrete") { testFileConcreteCpp("./benchmarks/wasm/pow.wat", Some("real_main"), expect=Some(List(1024))) } + test("start - concrete") { testFileConcreteCpp("./benchmarks/wasm/start.wat") } + test("fact - concrete") { testFileConcreteCpp("./benchmarks/wasm/fact.wat", None, expect=Some(List(120))) } + // TODO: Waiting more symbolic operators' implementations + // test("loop - concrete") { testFileConcreteCpp("./benchmarks/wasm/loop.wat", None, expect=Some(List(10))) } + test("even-odd - concrete") { testFileConcreteCpp("./benchmarks/wasm/even_odd.wat", None, expect=Some(List(1))) } + // TODO: Waiting symbolic memory's implementations + // test("load - concrete") { testFileConcreteCpp("./benchmarks/wasm/load.wat", None, expect=Some(List(1))) } + // test("btree - concrete") { testFileConcreteCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat") } + test("fib - concrete") { testFileConcreteCpp("./benchmarks/wasm/fib.wat", None, expect=Some(List(144))) } + test("tribonacci - concrete") { testFileConcreteCpp("./benchmarks/wasm/tribonacci.wat", None, expect=Some(List(504))) } + + // test("return - concrete") { + // Since all of the thrown exceptions had been captured in concolic driver, this test is not valid anymore + // intercept[java.lang.RuntimeException] { + // testFileConcreteCpp("./benchmarks/wasm/return.wat", Some("$real_main")) + // } + // } + + test("return_call - concrete") { + testFileConcreteCpp("./benchmarks/wasm/sum.wat", Some("sum10"), expect=Some(List(55))) + } + + test("block input - concrete") { + testFileConcreteCpp("./benchmarks/wasm/block.wat", Some("real_main"), expect=Some(List(9))) + } + test("loop block input - concrete") { + testFileConcreteCpp("./benchmarks/wasm/block.wat", Some("test_loop_input"), expect=Some(List(55))) + } + test("if block input - concrete") { + testFileConcreteCpp("./benchmarks/wasm/block.wat", Some("test_if_input"), expect=Some(List(25))) } + test("block input - poly br - concrete") { + testFileConcreteCpp("./benchmarks/wasm/block.wat", Some("test_poly_br"), expect=Some(List(0))) + } + test("loop block - poly br - concrete") { + testFileConcreteCpp("./benchmarks/wasm/loop_poly.wat", None, expect=Some(List(2, 1))) + } + + test("brtable-cpp - concrete") { + testFileConcreteCpp("./benchmarks/wasm/staged/brtable.wat") + } + } From 731ff9e14a6060b5c972bba2418ebaa3836baa8f Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 27 Aug 2025 19:28:49 -0400 Subject: [PATCH 23/82] c++17 compatible --- headers/wasm/smt_solver.hpp | 2 +- headers/wasm/utils.hpp | 14 ++++++++++++++ src/main/scala/wasm/StagedConcolicMiniWasm.scala | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index bc8cc9f9..504422f7 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -42,7 +42,7 @@ class Solver { z3::func_decl var = model[i]; z3::expr value = model.get_const_interp(var); std::string name = var.name().str(); - if (name.starts_with("s_")) { + if (starts_with(name, "s_")) { int id = std::stoi(name.substr(2)); if (id >= result.size()) { result.resize(id + 1); diff --git a/headers/wasm/utils.hpp b/headers/wasm/utils.hpp index ba57a1df..f814858d 100644 --- a/headers/wasm/utils.hpp +++ b/headers/wasm/utils.hpp @@ -36,4 +36,18 @@ #endif +#if __cplusplus < 202002L +#include + +inline bool starts_with(const std::string& str, const std::string& prefix) { + return str.size() >= prefix.size() && + std::equal(prefix.begin(), prefix.end(), str.begin()); +} +#else +#include +inline bool starts_with(const std::string& str, const std::string& prefix) { + return str.starts_with(prefix); +} +#endif + #endif // UTILS_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 769a0b85..cfb2803a 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -1725,7 +1725,7 @@ object WasmToCppCompiler { import sys.process._ val includeFlags = generated.headerFolders.map(f => s"-I$f").mkString(" ") val macroFlags = macros.map(m => s"-D$m").mkString(" ") - val command = s"g++ -std=c++20 $outputCpp -o $outputExe -O3 -g -l z3 " + includeFlags + " " + macroFlags + val command = s"g++ -std=c++17 $outputCpp -o $outputExe -O3 -g -l z3 " + includeFlags + " " + macroFlags if (command.! != 0) { throw new RuntimeException(s"Compilation failed for $outputCpp") } From ffa5670dbc470ae84124f14bb7845ec7a7d3b1fa Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 28 Aug 2025 20:49:33 -0400 Subject: [PATCH 24/82] fix --- headers/wasm/symbolic_rt.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 94351f07..566b5db6 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -325,7 +325,7 @@ struct IfElseNode : Node { IfElseNode(SymVal cond, NodeBox *parent, Snapshot_t snapshot) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)) {} + false_branch(std::make_unique(parent)), snapshot(snapshot) {} std::string to_string() override { std::string result = "IfElseNode {\n"; From b57929ad4fcda386a8e43a672d9dec44572867ff Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Fri, 29 Aug 2025 16:14:10 -0400 Subject: [PATCH 25/82] revert: don't split concrete/symbolic interpreter & don't support snapshot for now --- headers/wasm/symbolic_rt.hpp | 33 +- .../scala/wasm/StagedConcolicMiniWasm.scala | 511 +++++------------- 2 files changed, 156 insertions(+), 388 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 566b5db6..6efa7cfe 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -269,7 +269,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond, const Snapshot_t &snapshot); + std::monostate fillIfElseNode(SymVal cond); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -321,11 +321,10 @@ struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; - Snapshot_t snapshot; - IfElseNode(SymVal cond, NodeBox *parent, Snapshot_t snapshot) + IfElseNode(SymVal cond, NodeBox *parent) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)), snapshot(snapshot) {} + false_branch(std::make_unique(parent)) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -438,11 +437,10 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond, - const Snapshot_t &snapshot) { +inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { // fill the current NodeBox with an ifelse branch node when it's unexplored if (dynamic_cast(node.get())) { - node = std::make_unique(cond, this, snapshot); + node = std::make_unique(cond, this); } assert( dynamic_cast(node.get()) != nullptr && @@ -545,8 +543,8 @@ class ExploreTree_t { std::monostate fillFailedNode() { return cursor->fillFailedNode(); } - std::monostate fillIfElseNode(SymVal cond, const Snapshot_t &snapshot) { - return cursor->fillIfElseNode(cond, snapshot); + std::monostate fillIfElseNode(SymVal cond) { + return cursor->fillIfElseNode(cond); } std::monostate moveCursor(bool branch) { @@ -561,23 +559,6 @@ class ExploreTree_t { cursor = if_else_node->false_branch.get(); } - if (dynamic_cast(cursor->node.get())) { - // If we meet an unexplored node, resume the snapshot before and keep - // going - -#ifdef DEBUG - std::cout << "Resuming snapshot for unexplored node" << std::endl; -#endif - if (Reuse.is_reusing()) { - Reuse.turn_off_reusing(); - SymStack.reuse(if_else_node->snapshot); - } - } else if (dynamic_cast(cursor->node.get())) { - // if we are moving to a branch node, we must have reused the symbolic - // states - assert((!REUSE_MODE || Reuse.is_reusing()) && - "Moving to a branch node without reusing symbolic states"); - } return std::monostate(); } diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index cfb2803a..7372ede9 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -141,50 +141,11 @@ trait StagedWasmEvaluator extends SAIOps { ) } } - - } - - case class ContextTransition(startCtx: Context, history: List[Instr], endCtx: Context) { - def log(instr: Instr): ContextTransition = { - this.copy(history = instr :: history) - } - - def clearHistory: (Context, List[Instr], CleanCT) = { - (startCtx, history, CleanCT(endCtx)) - } - - def push(ty: ValueType): ContextTransition = { - this.copy(endCtx = endCtx.push(ty)) - } - - def peek: ValueType = { - endCtx.peek - } - - def pop(): (ValueType, ContextTransition) = { - val (ty, newCtx) = endCtx.pop() - (ty, this.copy(endCtx = newCtx)) - } - - def take(n: Int): ContextTransition = { - this.copy(endCtx = endCtx.take(n)) - } - - def shift(offset: Int, size: Int): ContextTransition = { - this.copy(endCtx = endCtx.shift(offset, size)) - } - } - - case class CleanCT(ctx: Context) - - // we can treat every CleanCT as a ContextTransition - implicit def toContextCT(ct: CleanCT): ContextTransition = { - ContextTransition(ct.ctx, Nil, ct.ctx) } type MCont[A] = Unit => A type Cont[A] = (MCont[A]) => A - type Trail[A] = List[CleanCT => Rep[Cont[A]]] + type Trail[A] = List[Context => Rep[Cont[A]]] // a cache storing the compiled code for each function, to reduce re-compilation val compileCache = new HashMap[Int, Rep[(MCont[Unit]) => Unit]] @@ -209,259 +170,243 @@ trait StagedWasmEvaluator extends SAIOps { "snapshot-make".reflectCtrlWith[Snapshot]() } - def isSymStateInUse: Rep[Boolean] = !ReuseManager.isReusing - def eval(insts: List[Instr], - kont: CleanCT => Rep[Cont[Unit]], + kont: Context => Rep[Cont[Unit]], mkont: Rep[MCont[Unit]], trail: Trail[Unit]) - (oldCT: ContextTransition): Rep[Unit] = { - if (insts.isEmpty) { - val (oldCtx, history, ct) = oldCT.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - return kont(ct)(mkont) - } + (implicit ctx: Context): Rep[Unit] = { + if (insts.isEmpty) return kont(ctx)(mkont) // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") // Predef.println(s"[DEBUG] Current context: $ctx") + val (inst, rest) = (insts.head, insts.tail) - val ct = oldCT.log(inst) inst match { case Drop => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() Stack.popC(ty) - eval(rest, kont, mkont, trail)(ct1) + Stack.popS(ty) + eval(rest, kont, mkont, trail)(newCtx) case WasmConst(num) => Stack.pushC(toStagedNum(num)) - val ct1 = ct.push(num.tipe(module)) - eval(rest, kont, mkont, trail)(ct1) + Stack.pushS(toStagedSymbolicNum(num)) + val newCtx = ctx.push(num.tipe(module)) + eval(rest, kont, mkont, trail)(newCtx) case Symbolic(ty) => - val id = Stack.popC(ty) + Stack.popC(ty) + val id = Stack.popS(ty) val symVal = id.makeSymbolic(ty) val num = SymEnv.read(symVal.s) Stack.pushC(ty.concreteTag(num)) - val ct1 = ct.pop()._2.push(ty) - eval(rest, kont, mkont, trail)(ct1) + Stack.pushS(symVal) + val newCtx = ctx.pop()._2.push(ty) + eval(rest, kont, mkont, trail)(newCtx) case LocalGet(i) => - Stack.pushC(Frames.getC(i)(ct.endCtx)) - val ct1 = ct.push(ct.endCtx.frameTypes(i)) - eval(rest, kont, mkont, trail)(ct1) + Stack.pushC(Frames.getC(i)) + Stack.pushS(Frames.getS(i)) + val newCtx = ctx.push(ctx.frameTypes(i)) + eval(rest, kont, mkont, trail)(newCtx) case LocalSet(i) => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() val num = Stack.popC(ty) + val sym = Stack.popS(ty) Frames.setC(i, num) - eval(rest, kont, mkont, trail)(ct1) + Frames.setS(i, sym) + eval(rest, kont, mkont, trail)(newCtx) case LocalTee(i) => - val ty = ct.peek + val ty = ctx.pop()._1 val num = Stack.peekC(ty) + val sym = Stack.peekS(ty) Frames.setC(i, num) - eval(rest, kont, mkont, trail)(ct) + Frames.setS(i, sym) + eval(rest, kont, mkont, trail)(ctx) case GlobalGet(i) => Stack.pushC(Globals.getC(i)) - val ct1 = ct.push(module.globals(i).ty.ty) - eval(rest, kont, mkont, trail)(ct1) + Stack.pushS(Globals.getS(i)) + val newCtx = ctx.push(module.globals(i).ty.ty) + eval(rest, kont, mkont, trail)(newCtx) case GlobalSet(i) => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() val num = Stack.popC(ty) + val sym = Stack.popS(ty) module.globals(i).ty match { case GlobalType(tipe, true) => { Globals.setC(i, num) + Globals.setS(i, sym) } case _ => throw new Exception("Cannot set immutable global") } - eval(rest, kont, mkont, trail)(ct1) + eval(rest, kont, mkont, trail)(newCtx) case Store(StoreOp(align, offset, ty, None)) => - val (ty1, ct1) = ct.pop() + val (ty1, newCtx1) = ctx.pop() val value = Stack.popC(ty1) - val (ty2, ct2) = ct1.pop() + val symValue = Stack.popS(ty1) + val (ty2, newCtx2) = newCtx1.pop() val addr = Stack.popC(ty2) + val symAddr = Stack.popS(ty2) Memory.storeInt(addr.toInt, offset, value.toInt) - eval(rest, kont, mkont, trail)(ct2) - case Nop => eval(rest, kont, mkont, trail)(ct) + eval(rest, kont, mkont, trail)(newCtx2) + case Nop => eval(rest, kont, mkont, trail) case Load(LoadOp(align, offset, ty, None, None)) => - val (ty1, ct1) = ct.pop() + val (ty1, newCtx1) = ctx.pop() val addr = Stack.popC(ty1) + Stack.popS(ty1) val num = Memory.loadIntC(addr.toInt, offset) + val sym = Memory.loadIntS(addr.toInt, offset) Stack.pushC(num) - val ct2 = ct1.push(ty) - eval(rest, kont, mkont, trail)(ct2) + Stack.pushS(sym) + val newCtx2 = newCtx1.push(ty) + eval(rest, kont, mkont, trail)(newCtx2) case MemorySize => ??? case MemoryGrow => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() val delta = Stack.popC(ty) + Stack.popS(ty) val ret = Memory.grow(delta.toInt) val retNum = Values.I32V(ret) // For now, we assume that the result of memory.grow only depends on the execution path, // we can relax this by turning it return to a symbol value and mimic the memory.grow's result as input. + val retSym = "Concrete".reflectCtrlWith[SymVal](retNum) Stack.pushC(I32C(retNum)) - val ct2 = ct1.push(NumType(I32Type)) - eval(rest, kont, mkont, trail)(ct2) + Stack.pushS(I32S(retSym)) + val newCtx2 = ctx.push(NumType(I32Type)) + eval(rest, kont, mkont, trail)(newCtx2) case MemoryFill => ??? case Unreachable => unreachable() case Test(op) => - val (ty, ct1) = ct.pop() + val (ty, newCtx1) = ctx.pop() val v = Stack.popC(ty) + val s = Stack.popS(ty) Stack.pushC(evalTestOpC(op, v)) - val ct2 = ct1.push(v.tipe) - eval(rest, kont, mkont, trail)(ct2) + Stack.pushS(evalTestOpS(op, s)) + val newCtx2 = newCtx1.push(v.tipe) + eval(rest, kont, mkont, trail)(newCtx2) case Unary(op) => - val (ty, ct1) = ct.pop() + val (ty, newCtx1) = ctx.pop() val v = Stack.popC(ty) + val s = Stack.popS(ty) val res = evalUnaryOpC(op, v) Stack.pushC(res) - val ct2 = ct1.push(res.tipe) - eval(rest, kont, mkont, trail)(ct2) + Stack.pushS(evalUnaryOpS(op, s)) + val newCtx2 = newCtx1.push(res.tipe) + eval(rest, kont, mkont, trail)(newCtx2) case Binary(op) => - val (ty2, ct1) = ct.pop() + val (ty2, newCtx1) = ctx.pop() val v2 = Stack.popC(ty2) - val (ty1, ct2) = ct1.pop() + val s2 = Stack.popS(ty2) + val (ty1, newCtx2) = newCtx1.pop() val v1 = Stack.popC(ty1) + val s1 = Stack.popS(ty1) val res = evalBinOpC(op, v1, v2) Stack.pushC(res) - val ct3 = ct2.push(res.tipe) - eval(rest, kont, mkont, trail)(ct3) + Stack.pushS(evalBinOpS(op, s1, s2)) + val newCtx3 = newCtx2.push(res.tipe) + eval(rest, kont, mkont, trail)(newCtx3) case Compare(op) => - val (ty2, ct1) = ct.pop() + val (ty2, newCtx1) = ctx.pop() val v2 = Stack.popC(ty2) - val (ty1, ct2) = ct1.pop() + val s2 = Stack.popS(ty2) + val (ty1, newCtx2) = newCtx1.pop() val v1 = Stack.popC(ty1) + val s1 = Stack.popS(ty1) val res = evalRelOpC(op, v1, v2) Stack.pushC(res) - val ct3 = ct2.push(res.tipe) - eval(rest, kont, mkont, trail)(ct3) + Stack.pushS(evalRelOpS(op, s1, s2)) + val newCtx3 = newCtx2.push(res.tipe) + eval(rest, kont, mkont, trail)(newCtx3) case WasmBlock(ty, inner) => // no need to modify the stack when entering a block // the type system guarantees that we will never take more than the input size from the stack val funcTy = ty.funcType - val exitSize = ct.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size val dummy = makeDummy - def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the block, stackSize =", Stack.size) - val offset = ct.endCtx.stackTypes.size - exitSize + val offset = restCtx.stackTypes.size - exitSize Stack.shiftC(offset, funcTy.out.size) - if (isSymStateInUse) { - Stack.shiftS(offset, funcTy.out.size) - } - val ct1 = ct.shift(offset, funcTy.out.size) - eval(rest, kont, mk, trail)(ct1) + Stack.shiftS(offset, funcTy.out.size) + val newRestCtx = restCtx.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(newRestCtx) }) - // TODO: extract this into a function - val (oldCtx, history, ct1) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - eval(inner, restK _, mkont, restK _ :: trail)(ct1) + eval(inner, restK _, mkont, restK _ :: trail) case Loop(ty, inner) => val funcTy = ty.funcType - val exitSize = ct.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size + val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size val dummy = makeDummy - def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the loop, stackSize =", Stack.size) - val offset = ct.endCtx.stackTypes.size - exitSize + val offset = restCtx.stackTypes.size - exitSize Stack.shiftC(offset, funcTy.out.size) - if (isSymStateInUse) { - Stack.shiftS(offset, funcTy.out.size) - } - val ct1 = ct.shift(offset, funcTy.out.size) - eval(rest, kont, mk, trail)(ct1) + Stack.shiftS(offset, funcTy.out.size) + val newRestCtx = restCtx.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(newRestCtx) }) - val enterSize = ct.endCtx.stackTypes.size - def loop(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + val enterSize = ctx.stackTypes.size + def loop(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Entered the loop, stackSize =", Stack.size) - val offset = ct.endCtx.stackTypes.size - enterSize + val offset = restCtx.stackTypes.size - enterSize Stack.shiftC(offset, funcTy.inps.size) - if (isSymStateInUse) { - Stack.shiftS(offset, funcTy.inps.size) - } - val ct1 = ct.shift(offset, funcTy.inps.size) - eval(inner, restK _, mk, loop _ :: trail)(ct1) + Stack.shiftS(offset, funcTy.inps.size) + val newRestCtx = restCtx.shift(offset, funcTy.inps.size) + eval(inner, restK _, mk, loop _ :: trail)(newRestCtx) }) - val (oldCtx, history, ct1) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - loop(ct1)(mkont) + loop(ctx)(mkont) case If(ty, thn, els) => val funcTy = ty.funcType - val (condTy, ct1) = ct.pop() + val (condTy, newCtx) = ctx.pop() val cond = Stack.popC(condTy) - val exitSize = ct1.endCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size - def restK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + val symCond = Stack.popS(condTy) + val exitSize = newCtx.stackTypes.size - funcTy.inps.size + funcTy.out.size + def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the if, stackSize =", Stack.size) - val offset = ct.endCtx.stackTypes.size - exitSize + val offset = restCtx.stackTypes.size - exitSize Stack.shiftC(offset, funcTy.out.size) - if (isSymStateInUse) { - Stack.shiftS(offset, funcTy.out.size) - } - val ct1 = ct.shift(offset, funcTy.out.size) - eval(rest, kont, mk, trail)(ct1) + Stack.shiftS(offset, funcTy.out.size) + val newRestCtx = restCtx.shift(offset, funcTy.out.size) + eval(rest, kont, mk, trail)(newRestCtx) }) - val (oldCtx, history, ct2) = ct1.clearHistory - if (isSymStateInUse) { - // when we are not reusing - evalSym(history)(oldCtx) - val snapshot = makeSnapshot() - val symCond = Stack.popS(condTy) - ExploreTree.fillWithIfElse(symCond.s, snapshot) - } + // TODO: put the cond.s to path condition + ExploreTree.fillWithIfElse(symCond.s) if (cond.toInt != 0) { ExploreTree.moveCursor(true) - eval(thn, restK _, mkont, restK _ :: trail)(ct2) + eval(thn, restK _, mkont, restK _ :: trail)(newCtx) } else { ExploreTree.moveCursor(false) - eval(els, restK _, mkont, restK _ :: trail)(ct2) + eval(els, restK _, mkont, restK _ :: trail)(newCtx) } () case Br(label) => info(s"Jump to $label") - val (oldCtx, history, ct1) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - trail(label)(ct1)(mkont) + trail(label)(ctx)(mkont) case BrIf(label) => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() val cond = Stack.popC(ty) - val (oldCtx, history, ct2) = ct1.clearHistory + val symCond = Stack.popS(ty) info(s"The br_if(${label})'s condition is ", cond.toInt) - if (isSymStateInUse) { - evalSym(history)(oldCtx) - val symCond = Stack.popS(ty) - val snapshot = makeSnapshot() - ExploreTree.fillWithIfElse(symCond.s, snapshot) - } + ExploreTree.fillWithIfElse(symCond.s) if (cond.toInt != 0) { info(s"Jump to $label") ExploreTree.moveCursor(true) - trail(label)(ct2)(mkont) + trail(label)(newCtx)(mkont) } else { info(s"Continue") ExploreTree.moveCursor(false) - eval(rest, kont, mkont, trail)(ct2) + eval(rest, kont, mkont, trail)(newCtx) } () case BrTable(labels, default) => - val (ty, ct1) = ct.pop() + val (ty, newCtx) = ctx.pop() val label = Stack.popC(ty) - val (oldCtx, history, ct2) = ct1.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } + val labelSym = Stack.popS(ty) def aux(choices: List[Int], idx: Int): Rep[Unit] = { - if (choices.isEmpty) trail(default)(ct2)(mkont) + if (choices.isEmpty) trail(default)(newCtx)(mkont) else { val cond = (label - toStagedNum(I32V(idx))).isZero() - if (isSymStateInUse) { - val labelSym = Stack.peekS(ty) - val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() - val snapshot = makeSnapshot() - ExploreTree.fillWithIfElse(condSym.s, snapshot) - } + val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() + ExploreTree.fillWithIfElse(condSym.s) if (cond.toInt != 0) { ExploreTree.moveCursor(true) - trail(choices.head)(ct2)(mkont) + trail(choices.head)(newCtx)(mkont) } else { ExploreTree.moveCursor(false) @@ -470,142 +415,12 @@ trait StagedWasmEvaluator extends SAIOps { } } aux(labels, 0) - if (isSymStateInUse) { - Stack.popS(ty) - } - () - case Return => - // return instruction is also stack-polymorphic - val (oldCtx, history, ct2) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - trail.last(ct2)(mkont) - case Call(f) => evalCall(rest, kont, mkont, trail, f, false)(ct) - case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true)(ct) + case Return => trail.last(ctx)(mkont) + case Call(f) => evalCall(rest, kont, mkont, trail, f, false) + case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true) case _ => val todo = "todo-op".reflectCtrlWith[Unit]() - eval(rest, kont, mkont, trail)(ct) - } - } - - def replayAndClearHistory(ct: ContextTransition): ContextTransition = { - val (oldCtx, history, ct1) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } - ct1 - } - - // call the symbolic interpreter to evaluate the history that just executed by - // concrete interpreter - def evalSym(history: List[Instr]) - (ctx: Context): Rep[Unit] = { - // val func = topFun((_: Rep[Unit]) => evalS(history.reverse)) - // func(()) - evalS(history.reverse)(ctx) - } - - def evalS(insts: List[Instr]) - (ctx: Context): Rep[Unit] = { - if (insts.isEmpty) return () - - // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") - // Predef.println(s"[DEBUG] Current context: $ctx") - val (inst, rest) = (insts.head, insts.tail) - inst match { - case Drop => - val (ty, newCtx) = ctx.pop() - Stack.popS(ty) - evalS(rest)(newCtx) - case WasmConst(num) => - Stack.pushS(toStagedSymbolicNum(num)) - val newCtx = ctx.push(num.tipe(module)) - evalS(rest)(newCtx) - case Symbolic(ty) => - val id = Stack.popS(ty) - val symVal = id.makeSymbolic(ty) - Stack.pushS(symVal) - val newCtx = ctx.pop()._2.push(ty) - evalS(rest)(newCtx) - case LocalGet(i) => - Stack.pushS(Frames.getS(i)(ctx)) - val newCtx = ctx.push(ctx.frameTypes(i)) - evalS(rest)(newCtx) - case LocalSet(i) => - val (ty, newCtx) = ctx.pop() - val sym = Stack.popS(ty) - Frames.setS(i, sym) - evalS(rest)(newCtx) - case LocalTee(i) => - val ty = ctx.pop()._1 - val sym = Stack.peekS(ty) - Frames.setS(i, sym) - evalS(rest)(ctx) - case GlobalGet(i) => - Stack.pushS(Globals.getS(i)) - val newCtx = ctx.push(module.globals(i).ty.ty) - evalS(rest)(newCtx) - case GlobalSet(i) => - val (ty, newCtx) = ctx.pop() - val sym = Stack.popS(ty) - module.globals(i).ty match { - case GlobalType(tipe, true) => { - Globals.setS(i, sym) - } - case _ => throw new Exception("Cannot set immutable global") - } - evalS(rest)(newCtx) - case Nop => evalS(rest)(ctx) - case Store(StoreOp(align, offset, ty, None)) => ??? - case Load(LoadOp(align, offset, ty, None, None)) => ??? - case MemorySize => ??? - case MemoryGrow => ??? - case MemoryFill => ??? - case Unreachable => unreachable() - case Test(op) => - val (ty, newCtx1) = ctx.pop() - val s = Stack.popS(ty) - Stack.pushS(evalTestOpS(op, s)) - val newCtx2 = newCtx1.push(s.tipe) - evalS(rest)(newCtx2) - case Unary(op) => - val (ty, newCtx1) = ctx.pop() - val s = Stack.popS(ty) - val res = evalUnaryOpS(op, s) - Stack.pushS(res) - val newCtx2 = newCtx1.push(res.tipe) - evalS(rest)(newCtx2) - case Binary(op) => - val (ty2, newCtx1) = ctx.pop() - val s2 = Stack.popS(ty2) - val (ty1, newCtx2) = newCtx1.pop() - val s1 = Stack.popS(ty1) - val res = evalBinOpS(op, s1, s2) - Stack.pushS(res) - val newCtx3 = newCtx2.push(res.tipe) - evalS(rest)(newCtx3) - case Compare(op) => - val (ty2, newCtx1) = ctx.pop() - val s2 = Stack.popS(ty2) - val (ty1, newCtx2) = newCtx1.pop() - val s1 = Stack.popS(ty1) - val res = evalRelOpS(op, s1, s2) - Stack.pushS(res) - val newCtx3 = newCtx2.push(res.tipe) - evalS(rest)(newCtx3) - case WasmBlock(ty, inner) => () - case Loop(ty, inner) => () - case If(ty, thn, els) => () - case Br(label) => () - case BrIf(label) => () - case BrTable(labels, default) => () - case Return => () - case Call(f) => () - case ReturnCall(f) => () - case _ => - val todo = "todo-op".reflectCtrlWith[Unit]() - evalS(rest)(ctx) + eval(rest, kont, mkont, trail) } } @@ -613,16 +428,12 @@ trait StagedWasmEvaluator extends SAIOps { def evalCall(rest: List[Instr], - kont: CleanCT => Rep[Cont[Unit]], + kont: Context => Rep[Cont[Unit]], mkont: Rep[MCont[Unit]], trail: Trail[Unit], funcIndex: Int, isTail: Boolean) - (implicit ct: ContextTransition): Rep[Unit] = { - val (oldCtx, history, ct1) = ct.clearHistory - if (isSymStateInUse) { - evalSym(history)(oldCtx) - } + (implicit ctx: Context): Rep[Unit] = { module.funcs(funcIndex) match { case FuncDef(_, FuncBodyDef(ty, _, bodyLocals, body)) => val locals = bodyLocals ++ ty.inps @@ -633,33 +444,30 @@ trait StagedWasmEvaluator extends SAIOps { val callee = topFun((mk: Rep[MCont[Unit]]) => { info(s"Entered the function at $funcIndex, stackSize =", Stack.size) // the return instruction is also stack polymorphic - def retK(ct: CleanCT): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + def retK(ctx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the function at $funcIndex, stackSize =", Stack.size) - val offset = ct.ctx.stackTypes.size - ty.out.size + val offset = ctx.stackTypes.size - ty.out.size Stack.shiftC(offset, ty.out.size) Stack.shiftS(offset, ty.out.size) mk(()) }) - eval(body, retK _, mk, retK _::Nil)(CleanCT(Context(Nil, locals))) + eval(body, retK _, mk, retK _::Nil)(Context(Nil, locals)) }) compileCache(funcIndex) = callee callee } // Predef.println(s"[DEBUG] locals size: ${locals.size}") - val ct2 = ct1.take(ty.inps.size) - val exitSize = ty.out.size + ct2.endCtx.stackTypes.size + val newCtx = ctx.take(ty.inps.size) + val argsC = Stack.takeC(ty.inps) + val argsS = Stack.takeS(ty.inps) if (isTail) { // when tail call, return to the caller's return continuation - val argsC = Stack.takeC(ty.inps) - Frames.popFrameC(ct2.endCtx.frameTypes.size) + Frames.popFrameC(ctx.frameTypes.size) + Frames.popFrameS(ctx.frameTypes.size) Frames.pushFrameC(locals) + Frames.pushFrameS(locals) Frames.putAllC(argsC) - if (isSymStateInUse) { - val argsS = Stack.takeS(ty.inps) - Frames.popFrameS(ct2.endCtx.frameTypes.size) - Frames.pushFrameS(locals) - Frames.putAllS(argsS) - } + Frames.putAllS(argsS) callee(mkont) } else { // We make a new trail by `restK`, since function creates a new block to escape @@ -668,38 +476,33 @@ trait StagedWasmEvaluator extends SAIOps { info(s"Exiting the function at $funcIndex, stackSize =", Stack.size) Frames.popFrameC(locals.size) Frames.popFrameS(locals.size) - val newCtx = ct2.endCtx.copy(stackTypes = ty.out.reverse ++ ct2.endCtx.stackTypes) - eval(rest, kont, mk, trail)(CleanCT(newCtx)) + eval(rest, kont, mk, trail)(newCtx.copy(stackTypes = ty.out.reverse ++ ctx.stackTypes.drop(ty.inps.size))) }) val dummy = makeDummy val newMKont: Rep[MCont[Unit]] = funHere((_u: Rep[Unit]) => { restK(mkont) }, dummy) - val argsC = Stack.takeC(ty.inps) Frames.pushFrameC(locals) + Frames.pushFrameS(locals) Frames.putAllC(argsC) - if (isSymStateInUse) { - val argsS = Stack.takeS(ty.inps) - Frames.pushFrameS(locals) - Frames.putAllS(argsS) - } + Frames.putAllS(argsS) callee(newMKont) } case Import("console", "log", _) | Import("spectest", "print_i32", _) => //println(s"[DEBUG] current stack: $stack") - val (ty, ct2) = ct1.pop() + val (ty, newCtx) = ctx.pop() val v = Stack.popC(ty) Stack.popS(ty) println(v.toInt) - eval(rest, kont, mkont, trail)(ct2) + eval(rest, kont, mkont, trail)(newCtx) case Import("console", "assert", _) => - val (ty, ct2) = ct1.pop() + val (ty, newCtx) = ctx.pop() val v = Stack.popC(ty) // TODO: We should also add s into exploration tree val s = Stack.popS(ty) runtimeAssert(v.toInt != 0) - eval(rest, kont, mkont, trail)(ct2) + eval(rest, kont, mkont, trail)(newCtx) case Import(_, _, _) => throw new Exception(s"Unknown import at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") } @@ -811,7 +614,7 @@ trait StagedWasmEvaluator extends SAIOps { resetStacks() Frames.pushFrameC(locals) Frames.pushFrameS(locals) - eval(instrs, _ => forwardKont, mkont, ((_: CleanCT) => forwardKont)::Nil)(CleanCT(Context(Nil, locals))) + eval(instrs, (_: Context) => forwardKont, mkont, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) Frames.popFrameC(locals.size) Frames.popFrameS(locals.size) } @@ -1074,8 +877,8 @@ trait StagedWasmEvaluator extends SAIOps { // Exploration tree, object ExploreTree { - def fillWithIfElse(sym: Rep[SymVal], snapshot: Rep[Snapshot]): Rep[Unit] = { - "tree-fill-if-else".reflectCtrlWith[Unit](sym, snapshot) + def fillWithIfElse(s: Rep[SymVal]): Rep[Unit] = { + "tree-fill-if-else".reflectCtrlWith[Unit](s) } def fillWithFinished(): Rep[Unit] = { @@ -1102,20 +905,6 @@ trait StagedWasmEvaluator extends SAIOps { } } - object ReuseManager { - def isReusing: Rep[Boolean] = { - "reuse-is-reusing".reflectCtrlWith[Boolean]() - } - - def turnOnReuse(): Rep[Unit] = { - "reuse-turn-on".reflectCtrlWith[Unit]() - } - - def turnOffReuse(): Rep[Unit] = { - "reuse-turn-off".reflectCtrlWith[Unit]() - } - } - // runtime Num type implicit class StagedConcreteNumOps(num: StagedConcreteNum) { @@ -1624,8 +1413,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("SymEnv.read("); shallow(sym); emit(")") case Node(_, "assert-true", List(cond), _) => emit("GENSYM_ASSERT("); shallow(cond); emit(")") - case Node(_, "tree-fill-if-else", List(sym, snapshot), _) => - emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(", "); shallow(snapshot); emit(")") + case Node(_, "tree-fill-if-else", List(sym), _) => + emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(")") case Node(_, "tree-fill-finished", List(), _) => emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b), _) => @@ -1636,8 +1425,6 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.dump_graphviz("); shallow(f); emit(")") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") - case Node(_, "reuse-is-reusing", List(), _) => - emit("Reuse.is_reusing()") case Node(_, "dummy", _, _) => emit("std::monostate()") case Node(_, "dummy-op", _, _) => emit("std::monostate()") case Node(_, "no-op", _, _) => From 1bdb7da1a3d78e6e2e93be8f880f4f2ba0326d0d Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Fri, 29 Aug 2025 21:16:43 -0400 Subject: [PATCH 26/82] introduce a SnapshotNode, which currently behaves same as UnexploredNode --- headers/wasm/concolic_driver.hpp | 2 +- headers/wasm/symbolic_rt.hpp | 43 ++++++++++++++++--- .../scala/wasm/StagedConcolicMiniWasm.scala | 3 ++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 427a0de8..ab14525e 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -38,8 +38,8 @@ class ManagedConcolicCleanup { }; inline void ConcolicDriver::run() { - ManagedConcolicCleanup cleanup{*this}; while (true) { + ManagedConcolicCleanup cleanup{*this}; ExploreTree.reset_cursor(); auto unexplored = ExploreTree.pick_unexplored(); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 6efa7cfe..7931a3c3 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -273,7 +273,8 @@ struct NodeBox { std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); - + std::monostate fillSnapshotNode(); + bool isUnexplored() const; std::vector collect_path_conds(); }; @@ -384,6 +385,22 @@ struct UnExploredNode : Node { } }; +struct SnapshotNode : Node { + SnapshotNode() {} + std::string to_string() override { return "SnapshotNode"; } + +protected: + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "Snapshot", "box", "lightblue"); + + if (parent_dot_id != -1) { + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); + } + } +}; + struct Finished : Node { Finished() {} std::string to_string() override { return "FinishedNode"; } @@ -439,7 +456,7 @@ inline NodeBox::NodeBox(NodeBox *parent) inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { // fill the current NodeBox with an ifelse branch node when it's unexplored - if (dynamic_cast(node.get())) { + if (this->isUnexplored()) { node = std::make_unique(cond, this); } assert( @@ -448,8 +465,15 @@ inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { return std::monostate(); } +inline std::monostate NodeBox::fillSnapshotNode() { + if (this->isUnexplored()) { + node = std::make_unique(); + } + return std::monostate(); +} + inline std::monostate NodeBox::fillFinishedNode() { - if (dynamic_cast(node.get())) { + if (this->isUnexplored()) { node = std::make_unique(); } else { assert(dynamic_cast(node.get()) != nullptr); @@ -458,7 +482,7 @@ inline std::monostate NodeBox::fillFinishedNode() { } inline std::monostate NodeBox::fillFailedNode() { - if (dynamic_cast(node.get())) { + if (this->isUnexplored()) { node = std::make_unique(); } else { assert(dynamic_cast(node.get()) != nullptr); @@ -467,7 +491,7 @@ inline std::monostate NodeBox::fillFailedNode() { } inline std::monostate NodeBox::fillUnreachableNode() { - if (dynamic_cast(node.get())) { + if (this->isUnexplored()) { node = std::make_unique(); } else { assert(dynamic_cast(node.get()) != nullptr); @@ -475,6 +499,11 @@ inline std::monostate NodeBox::fillUnreachableNode() { return std::monostate(); } +inline bool NodeBox::isUnexplored() const { + return dynamic_cast(node.get()) != nullptr || + dynamic_cast(node.get()) != nullptr; +} + inline std::vector NodeBox::collect_path_conds() { auto box = this; auto result = std::vector(); @@ -554,8 +583,10 @@ class ExploreTree_t { if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); if (branch) { + if_else_node->false_branch->fillSnapshotNode(); cursor = if_else_node->true_branch.get(); } else { + if_else_node->true_branch->fillSnapshotNode(); cursor = if_else_node->false_branch.get(); } @@ -599,7 +630,7 @@ class ExploreTree_t { private: NodeBox *pick_unexplored_of(NodeBox *node) { - if (dynamic_cast(node->node.get()) != nullptr) { + if (node->isUnexplored()) { return node; } auto if_else_node = dynamic_cast(node->node.get()); diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 7372ede9..d488e7d1 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -404,6 +404,9 @@ trait StagedWasmEvaluator extends SAIOps { val cond = (label - toStagedNum(I32V(idx))).isZero() val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() ExploreTree.fillWithIfElse(condSym.s) + // When moving the cursor to a branch, we mark another branch as + // snapshotNode (this is done by moveCursor's runtime implementation) + // TODO: store snapshot into this snapshot node if (cond.toInt != 0) { ExploreTree.moveCursor(true) trail(choices.head)(newCtx)(mkont) From 64dce3263ad69956cd9636bab4f6787428e775ed Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 30 Aug 2025 14:11:56 -0400 Subject: [PATCH 27/82] fill snapshot into SnapshotNode --- headers/wasm/symbolic_rt.hpp | 27 +++--- .../scala/wasm/StagedConcolicMiniWasm.scala | 88 +++++++++++++------ 2 files changed, 76 insertions(+), 39 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 7931a3c3..e96adad9 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -228,7 +228,7 @@ class SymFrames_t { // A snapshot of the symbolic state and execution context (control) class Snapshot_t { public: - explicit Snapshot_t(); + explicit Snapshot_t(Cont_t cont, MCont_t mcont); SymStack_t get_stack() const { return stack; } SymFrames_t get_frames() const { return frames; } @@ -236,6 +236,9 @@ class Snapshot_t { private: SymStack_t stack; SymFrames_t frames; + // The continuation at the snapshot point + Cont_t cont; + MCont_t mcont; }; inline void SymStack_t::reuse(Snapshot_t snapshot) { @@ -273,7 +276,7 @@ struct NodeBox { std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); - std::monostate fillSnapshotNode(); + std::monostate fillSnapshotNode(Snapshot_t snapshot); bool isUnexplored() const; std::vector collect_path_conds(); }; @@ -386,7 +389,7 @@ struct UnExploredNode : Node { }; struct SnapshotNode : Node { - SnapshotNode() {} + SnapshotNode(Snapshot_t snapshot) : snapshot(snapshot) {} std::string to_string() override { return "SnapshotNode"; } protected: @@ -399,6 +402,9 @@ struct SnapshotNode : Node { graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); } } + +private: + Snapshot_t snapshot; }; struct Finished : Node { @@ -465,9 +471,9 @@ inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { return std::monostate(); } -inline std::monostate NodeBox::fillSnapshotNode() { +inline std::monostate NodeBox::fillSnapshotNode(Snapshot_t snapshot) { if (this->isUnexplored()) { - node = std::make_unique(); + node = std::make_unique(snapshot); } return std::monostate(); } @@ -545,12 +551,11 @@ class Reuse_t { static Reuse_t Reuse; -inline Snapshot_t::Snapshot_t() : stack(SymStack), frames(SymFrames) { +inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont) + : stack(SymStack), frames(SymFrames), cont(cont), mcont(mcont) { #ifdef DEBUG std::cout << "Creating snapshot of size " << stack.size() << std::endl; #endif - assert(!Reuse.is_reusing() && - "Creating snapshot while reusing the symbolic stack"); } class ExploreTree_t { @@ -576,17 +581,17 @@ class ExploreTree_t { return cursor->fillIfElseNode(cond); } - std::monostate moveCursor(bool branch) { + std::monostate moveCursor(bool branch, Snapshot_t snapshot) { assert(cursor != nullptr); auto if_else_node = dynamic_cast(cursor->node.get()); assert( if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); if (branch) { - if_else_node->false_branch->fillSnapshotNode(); + if_else_node->false_branch->fillSnapshotNode(snapshot); cursor = if_else_node->true_branch.get(); } else { - if_else_node->true_branch->fillSnapshotNode(); + if_else_node->true_branch->fillSnapshotNode(snapshot); cursor = if_else_node->false_branch.get(); } diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index d488e7d1..9b34bfba 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -165,9 +165,9 @@ trait StagedWasmEvaluator extends SAIOps { trait Snapshot // Create a snapshot of the symbolic execution, we should ensure that current symstack is in use - // We don't need to store the control information, since the control is totally decided by concrete states - def makeSnapshot(): Rep[Snapshot] = { - "snapshot-make".reflectCtrlWith[Snapshot]() + // We need to store the control information, so we can resume the execution later + def makeSnapshot(kont: Rep[Cont[Unit]], mkont: Rep[MCont[Unit]]): Rep[Snapshot] = { + "snapshot-make".reflectCtrlWith[Snapshot](kont, mkont) } def eval(insts: List[Instr], @@ -365,14 +365,23 @@ trait StagedWasmEvaluator extends SAIOps { val newRestCtx = restCtx.shift(offset, funcTy.out.size) eval(rest, kont, mk, trail)(newRestCtx) }) - // TODO: put the cond.s to path condition ExploreTree.fillWithIfElse(symCond.s) + def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info("Entering the true branch of the if") + eval(thn, restK _, mk, restK _ :: trail)(newCtx) + }) + def elsK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info("Entering the false branch of the if") + eval(els, restK _, mk, restK _ :: trail)(newCtx) + }) if (cond.toInt != 0) { - ExploreTree.moveCursor(true) - eval(thn, restK _, mkont, restK _ :: trail)(newCtx) + val snapshot = makeSnapshot(elsK, mkont) + ExploreTree.moveCursor(true, snapshot) + thnK(mkont) } else { - ExploreTree.moveCursor(false) - eval(els, restK _, mkont, restK _ :: trail)(newCtx) + val snapshot = makeSnapshot(thnK, mkont) + ExploreTree.moveCursor(false, snapshot) + elsK(mkont) } () case Br(label) => @@ -384,40 +393,63 @@ trait StagedWasmEvaluator extends SAIOps { val symCond = Stack.popS(ty) info(s"The br_if(${label})'s condition is ", cond.toInt) ExploreTree.fillWithIfElse(symCond.s) + def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + trail(label)(newCtx)(mk) + }) + def elsK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + eval(rest, kont, mk, trail)(newCtx) + }) if (cond.toInt != 0) { info(s"Jump to $label") - ExploreTree.moveCursor(true) - trail(label)(newCtx)(mkont) + val snapshot = makeSnapshot(elsK, mkont) + ExploreTree.moveCursor(true, snapshot) + thnK(mkont) } else { info(s"Continue") - ExploreTree.moveCursor(false) - eval(rest, kont, mkont, trail)(newCtx) + val snapshot = makeSnapshot(thnK, mkont) + ExploreTree.moveCursor(false, snapshot) + elsK(mkont) } () case BrTable(labels, default) => val (ty, newCtx) = ctx.pop() - val label = Stack.popC(ty) - val labelSym = Stack.popS(ty) - def aux(choices: List[Int], idx: Int): Rep[Unit] = { - if (choices.isEmpty) trail(default)(newCtx)(mkont) - else { + def aux(choices: List[Int], idx: Int, mkont: Rep[MCont[Unit]]): Rep[Unit] = { + if (choices.isEmpty) { + Stack.popC(ty) + Stack.popS(ty) + trail(default)(newCtx)(mkont) + } else { + val label = Stack.peekC(ty) + val labelSym = Stack.peekS(ty) val cond = (label - toStagedNum(I32V(idx))).isZero() val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() ExploreTree.fillWithIfElse(condSym.s) // When moving the cursor to a branch, we mark another branch as // snapshotNode (this is done by moveCursor's runtime implementation) // TODO: store snapshot into this snapshot node + def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info("Entering the true branch of the br_table") + Stack.popC(ty) + Stack.popS(ty) + trail(choices.head)(newCtx)(mk) + }) + def elsK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info("Entering the false branch of the br_table") + aux(choices.tail, idx + 1, mk) + }) if (cond.toInt != 0) { - ExploreTree.moveCursor(true) - trail(choices.head)(newCtx)(mkont) + val snapshot = makeSnapshot(elsK, mkont) + ExploreTree.moveCursor(true, snapshot) + thnK(mkont) } else { - ExploreTree.moveCursor(false) - aux(choices.tail, idx + 1) + val snapshot = makeSnapshot(thnK, mkont) + ExploreTree.moveCursor(false, snapshot) + elsK(mkont) } } } - aux(labels, 0) + aux(labels, 0, mkont) case Return => trail.last(ctx)(mkont) case Call(f) => evalCall(rest, kont, mkont, trail, f, false) case ReturnCall(f) => evalCall(rest, kont, mkont, trail, f, true) @@ -888,9 +920,9 @@ trait StagedWasmEvaluator extends SAIOps { "tree-fill-finished".reflectCtrlWith[Unit]() } - def moveCursor(branch: Boolean): Rep[Unit] = { + def moveCursor(branch: Boolean, snapshot: Rep[Snapshot]): Rep[Unit] = { // when moving cursor from to an unexplored node, we need to change the reuse state - "tree-move-cursor".reflectCtrlWith[Unit](branch) + "tree-move-cursor".reflectCtrlWith[Unit](branch, snapshot) } def print(): Rep[Unit] = { @@ -1323,8 +1355,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.pop()") case Node(_, "sym-stack-pop", _, _) => emit("SymStack.pop()") - case Node(_, "snapshot-make", _, _) => - emit("Snapshot_t()") + case Node(_, "snapshot-make", List(k, mk), _) => + emit("Snapshot_t("); shallow(k); emit(", "); shallow(mk); emit(")") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(")") case Node(_, "sym-frame-pop", List(i), _) => @@ -1420,8 +1452,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(")") case Node(_, "tree-fill-finished", List(), _) => emit("ExploreTree.fillFinishedNode()") - case Node(_, "tree-move-cursor", List(b), _) => - emit("ExploreTree.moveCursor("); shallow(b); emit(")") + case Node(_, "tree-move-cursor", List(b, snapshot), _) => + emit("ExploreTree.moveCursor("); shallow(b); emit(", "); shallow(snapshot); emit(")") case Node(_, "tree-print", List(), _) => emit("ExploreTree.print()") case Node(_, "tree-dump-graphviz", List(f), _) => From 463871cf3c5ce2f30cb64fa3856f92f263c99a56 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 31 Aug 2025 16:36:53 -0400 Subject: [PATCH 28/82] snapshot reuse via continuation more tests should be added --- headers/wasm/concolic_driver.hpp | 12 +- headers/wasm/concrete_rt.hpp | 24 +++ headers/wasm/controls.hpp | 9 +- headers/wasm/symbolic_rt.hpp | 157 ++++++++++++++---- .../genwasym/TestStagedConcolicEval.scala | 6 +- 5 files changed, 172 insertions(+), 36 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index ab14525e..1c2fcc2e 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -38,9 +38,9 @@ class ManagedConcolicCleanup { }; inline void ConcolicDriver::run() { + ExploreTree.reset_cursor(); while (true) { ManagedConcolicCleanup cleanup{*this}; - ExploreTree.reset_cursor(); auto unexplored = ExploreTree.pick_unexplored(); if (!unexplored) { @@ -55,11 +55,19 @@ inline void ConcolicDriver::run() { continue; } auto new_env = result.value(); + + // update global symbolic environment from SMT solved model SymEnv.update(std::move(new_env)); try { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); - entrypoint(); + if (auto snapshot_node = + dynamic_cast(unexplored->node.get())) { + snapshot_node->get_snapshot().resume_execution(SymEnv, unexplored); + } else { + entrypoint(); + } + GENSYM_INFO("Execution finished successfully with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); } catch (...) { diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index a9abccf2..16642067 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -1,6 +1,7 @@ #ifndef WASM_CONCRETE_RT_HPP #define WASM_CONCRETE_RT_HPP +#include "wasm/utils.hpp" #include #include #include @@ -120,6 +121,16 @@ class Stack_t { void reset() { count = 0; } + void resize(int32_t new_size) { + assert(new_size >= 0); + count = new_size; + } + + void set_from_front(int32_t index, const Num &num) { + assert(index >= 0 && index < count); + stack_ptr[index] = num; + } + private: int32_t count; Num *stack_ptr; @@ -152,6 +163,19 @@ class Frames_t { void reset() { count = 0; } + size_t size() const { return count; } + + void set_from_front(int32_t index, const Num &num) { + GENSYM_DBG(index); + assert(index >= 0 && index < count && "Index out of bounds"); + stack_ptr[index] = num; + } + + void resize(int32_t new_size) { + assert(new_size >= 0); + count = new_size; + } + private: int32_t count; Num *stack_ptr; diff --git a/headers/wasm/controls.hpp b/headers/wasm/controls.hpp index 16fa5136..513f0692 100644 --- a/headers/wasm/controls.hpp +++ b/headers/wasm/controls.hpp @@ -1,5 +1,12 @@ + +#ifndef WASM_CONTROLS_HPP +#define WASM_CONTROLS_HPP + #include + #include using MCont_t = std::function; -using Cont_t = std::function; \ No newline at end of file +using Cont_t = std::function; + +#endif // WASM_CONTROLS_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index e96adad9..d18ea609 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -3,6 +3,7 @@ #include "concrete_rt.hpp" #include "controls.hpp" +#include "utils.hpp" #include #include #include @@ -71,6 +72,8 @@ struct SymVal { SymVal gt(const SymVal &other) const; SymVal geq(const SymVal &other) const; SymVal negate() const; + + bool is_concrete() const; }; static SymVal make_symbolic(int index) { @@ -145,6 +148,10 @@ inline SymVal SymVal::makeSymbolic() const { } } +inline bool SymVal::is_concrete() const { + return dynamic_cast(symptr.get()) != nullptr; +} + class Snapshot_t; class SymStack_t { @@ -186,6 +193,8 @@ class SymStack_t { size_t size() const { return stack.size(); } + SymVal operator[](size_t index) const { return stack[index]; } + private: std::vector stack; }; @@ -222,9 +231,17 @@ class SymFrames_t { void reuse(Snapshot_t snapshot); + size_t size() const { return stack.size(); } + + SymVal operator[](size_t index) const { return stack[index]; } + +private: std::vector stack; }; +struct NodeBox; +struct SymEnv_t; + // A snapshot of the symbolic state and execution context (control) class Snapshot_t { public: @@ -233,6 +250,8 @@ class Snapshot_t { SymStack_t get_stack() const { return stack; } SymFrames_t get_frames() const { return frames; } + std::monostate resume_execution(SymEnv_t &sym_env, NodeBox *node) const; + private: SymStack_t stack; SymFrames_t frames; @@ -391,6 +410,7 @@ struct UnExploredNode : Node { struct SnapshotNode : Node { SnapshotNode(Snapshot_t snapshot) : snapshot(snapshot) {} std::string to_string() override { return "SnapshotNode"; } + const Snapshot_t &get_snapshot() const { return snapshot; } protected: void generate_dot(std::ostream &os, int parent_dot_id, @@ -479,6 +499,7 @@ inline std::monostate NodeBox::fillSnapshotNode(Snapshot_t snapshot) { } inline std::monostate NodeBox::fillFinishedNode() { + GENSYM_DBG("Filling with a Finished Node"); if (this->isUnexplored()) { node = std::make_unique(); } else { @@ -491,6 +512,11 @@ inline std::monostate NodeBox::fillFailedNode() { if (this->isUnexplored()) { node = std::make_unique(); } else { + if (auto if_else_node = dynamic_cast(node.get())) { + GENSYM_DBG(typeid(*if_else_node).name()); + } else if (auto finished_node = dynamic_cast(node.get())) { + GENSYM_DBG(typeid(*finished_node).name()); + } assert(dynamic_cast(node.get()) != nullptr); } return std::monostate(); @@ -533,24 +559,6 @@ inline std::vector NodeBox::collect_path_conds() { return result; } -class Reuse_t { -public: - Reuse_t() : reuse_flag(false) {} - bool is_reusing() { - // we are in reuse mode and the flag is set - return REUSE_MODE && reuse_flag; - } - - void turn_on_reusing() { reuse_flag = true; } - - void turn_off_reusing() { reuse_flag = false; } - -private: - bool reuse_flag; -}; - -static Reuse_t Reuse; - inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont) : stack(SymStack), frames(SymFrames), cont(cont), mcont(mcont) { #ifdef DEBUG @@ -564,13 +572,15 @@ class ExploreTree_t { : root(std::make_unique(nullptr)), cursor(root.get()) {} void reset_cursor() { + GENSYM_INFO("Resetting cursor to root"); // Reset the cursor to the root of the tree cursor = root.get(); - Reuse.turn_off_reusing(); - // if root cursor is a branch node, then we can reuse the snapshot inside it - if (auto ite = dynamic_cast(cursor->node.get())) { - Reuse.turn_on_reusing(); - } + } + + void set_cursor(NodeBox *new_cursor) { + GENSYM_INFO("Setting cursor to a new node"); + cursor = new_cursor; + assert(dynamic_cast(cursor->node.get()) != nullptr); } std::monostate fillFinishedNode() { return cursor->fillFinishedNode(); } @@ -656,18 +666,23 @@ static ExploreTree_t ExploreTree; class SymEnv_t { public: - Num read(SymVal sym) { - auto symbol = dynamic_cast(sym.symptr.get()); - assert(symbol); - if (symbol->get_id() >= map.size()) { - map.resize(symbol->get_id() + 1); + Num read(const Symbol &symbol) { + if (symbol.get_id() >= map.size()) { + map.resize(symbol.get_id() + 1); } #if DEBUG - std::cout << "Read symbol: " << symbol->get_id() + std::cout << "Read symbol: " << symbol.get_id() << " from symbolic environment" << std::endl; std::cout << "Current symbolic environment: " << to_string() << std::endl; #endif - return map[symbol->get_id()]; + + return map[symbol.get_id()]; + } + + Num read(SymVal sym) { + auto symbol = dynamic_cast(sym.symptr.get()); + assert(symbol); + return read(*symbol); } void update(std::vector new_env) { map = std::move(new_env); } @@ -684,10 +699,92 @@ class SymEnv_t { return result; } + size_t size() const { return map.size(); } + private: std::vector map; // The symbolic environment, a vector of Num }; static SymEnv_t SymEnv; +// TODO: reduce the re-computation of the same symbolic expression, it's better +// if it can be done by the smt solver +static Num eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { + if (auto concrete = dynamic_cast(sym.symptr.get())) { + return concrete->value; + } else if (auto operation = dynamic_cast(sym.symptr.get())) { + // If it's a operation, we need to evaluate it + auto lhs = eval_sym_expr(operation->lhs, sym_env); + auto rhs = eval_sym_expr(operation->rhs, sym_env); + switch (operation->op) { + case ADD: + return lhs + rhs; + case SUB: + return lhs - rhs; + case MUL: + return lhs * rhs; + case DIV: + return lhs / rhs; + case LT: + return lhs < rhs; + case LEQ: + return lhs <= rhs; + case GT: + return lhs > rhs; + case GEQ: + return lhs >= rhs; + default: + throw std::runtime_error("Operation not supported: " + + std::to_string(operation->op)); + } + } else if (auto symbol = dynamic_cast(sym.symptr.get())) { + auto sym_id = symbol->get_id(); + GENSYM_INFO("Reading symbol: " + std::to_string(sym_id)); + return sym_env.read(sym); + } + throw std::runtime_error("Not supported symbolic expression"); +} + +static void resume_conc_stack(const SymStack_t &sym_stack, Stack_t &stack, + SymEnv_t &sym_env) { + stack.resize(sym_stack.size()); + for (size_t i = 0; i < sym_stack.size(); ++i) { + auto sym = sym_stack[i]; + auto conc = eval_sym_expr(sym, sym_env); + stack.set_from_front(i, conc); + } +} + +static void resume_conc_frames(const SymFrames_t &sym_frame, Frames_t &frames, + SymEnv_t &sym_env) { + frames.resize(sym_frame.size()); + for (size_t i = 0; i < sym_frame.size(); ++i) { + auto sym = sym_frame[i]; + auto conc = eval_sym_expr(sym, sym_env); + frames.set_from_front(i, conc); + } +} + +static void resume_conc_states(const SymStack_t &sym_stack, + const SymFrames_t &sym_frame, Stack_t &stack, + Frames_t &frames, SymEnv_t &sym_env) { + resume_conc_stack(sym_stack, stack, sym_env); + resume_conc_frames(sym_frame, frames, sym_env); +} + +inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, + NodeBox *node) const { + // Reset explore tree's cursor + ExploreTree.set_cursor(node); + + // Restore the symbolic state from the snapshot + GENSYM_INFO("Reusing symbolic state from snapshot"); + SymStack = stack; + SymFrames = frames; + // Restore the concrete states from the symbolic states + resume_conc_states(stack, frames, Stack, Frames, sym_env); + // Resume execution from the continuation + return cont(mcont); +} + #endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 48c24634..5a77f58d 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -42,13 +42,13 @@ class TestStagedConcolicEval extends FunSuite { }) } - test("ack-cpp") { testFileConcolicCpp("./benchmarks/wasm/ack.wat", Some("real_main")) } + test("ack-cpp-concolic") { testFileConcolicCpp("./benchmarks/wasm/ack.wat", Some("real_main")) } - test("bug-finding") { + test("bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main")) } - test("brtable-bug-finding") { + test("brtable-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/staged/brtable_concolic.wat") } From 261c650e78956204ae4b190e7841b27e97a0084f Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 1 Sep 2025 13:28:40 -0400 Subject: [PATCH 29/82] remove debug printings --- headers/wasm/concrete_rt.hpp | 1 - headers/wasm/symbolic_rt.hpp | 6 ------ 2 files changed, 7 deletions(-) diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 16642067..76c2537a 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -166,7 +166,6 @@ class Frames_t { size_t size() const { return count; } void set_from_front(int32_t index, const Num &num) { - GENSYM_DBG(index); assert(index >= 0 && index < count && "Index out of bounds"); stack_ptr[index] = num; } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index d18ea609..730e778b 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -499,7 +499,6 @@ inline std::monostate NodeBox::fillSnapshotNode(Snapshot_t snapshot) { } inline std::monostate NodeBox::fillFinishedNode() { - GENSYM_DBG("Filling with a Finished Node"); if (this->isUnexplored()) { node = std::make_unique(); } else { @@ -512,11 +511,6 @@ inline std::monostate NodeBox::fillFailedNode() { if (this->isUnexplored()) { node = std::make_unique(); } else { - if (auto if_else_node = dynamic_cast(node.get())) { - GENSYM_DBG(typeid(*if_else_node).name()); - } else if (auto finished_node = dynamic_cast(node.get())) { - GENSYM_DBG(typeid(*finished_node).name()); - } assert(dynamic_cast(node.get()) != nullptr); } return std::monostate(); From 1c6a0452bf41479c861a9d4f2fada72edad5574a Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 3 Sep 2025 20:37:19 -0400 Subject: [PATCH 30/82] give every branch node an ID --- headers/wasm/concolic_driver.hpp | 2 +- headers/wasm/symbolic_rt.hpp | 15 +++---- .../scala/wasm/StagedConcolicMiniWasm.scala | 42 +++++++++++++++---- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 1c2fcc2e..e0b9e726 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -100,7 +100,7 @@ static void start_concolic_execution_with( } static void start_concolic_execution_with( - std::function entrypoint) { + std::function entrypoint, int branchCount) { const char *env_tree_file = std::getenv("TREE_FILE"); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 730e778b..dfc0f7b1 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -291,7 +291,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond); + std::monostate fillIfElseNode(SymVal cond, int id); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -344,10 +344,11 @@ struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; + int id; - IfElseNode(SymVal cond, NodeBox *parent) + IfElseNode(SymVal cond, NodeBox *parent, int id) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)) {} + false_branch(std::make_unique(parent)), id(id) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -480,10 +481,10 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { +inline std::monostate NodeBox::fillIfElseNode(SymVal cond, int id) { // fill the current NodeBox with an ifelse branch node when it's unexplored if (this->isUnexplored()) { - node = std::make_unique(cond, this); + node = std::make_unique(cond, this, id); } assert( dynamic_cast(node.get()) != nullptr && @@ -581,8 +582,8 @@ class ExploreTree_t { std::monostate fillFailedNode() { return cursor->fillFailedNode(); } - std::monostate fillIfElseNode(SymVal cond) { - return cursor->fillIfElseNode(cond); + std::monostate fillIfElseNode(SymVal cond, int id) { + return cursor->fillIfElseNode(cond, id); } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 9b34bfba..5630e18d 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -19,6 +19,26 @@ import gensym.wasm.symbolic.Concrete import gensym.wasm.symbolic.ExploreTree import gensym.structure.freer.Explore +object Counter { + var currentId: Int = 0 + private val dict = new HashMap[WIR, Int]() + + def reset(): Unit = { + currentId = 0 + dict.clear() + } + + def getId(wir: WIR): Int = { + if (dict.contains(wir)) { + dict(wir) + } else { + val id = currentId + currentId += 1 + dict(wir) = id + id + } + } +} @virtualize trait StagedWasmEvaluator extends SAIOps { def module: ModuleInstance @@ -365,7 +385,8 @@ trait StagedWasmEvaluator extends SAIOps { val newRestCtx = restCtx.shift(offset, funcTy.out.size) eval(rest, kont, mk, trail)(newRestCtx) }) - ExploreTree.fillWithIfElse(symCond.s) + val id = Counter.getId(inst) + ExploreTree.fillWithIfElse(symCond.s, id) def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info("Entering the true branch of the if") eval(thn, restK _, mk, restK _ :: trail)(newCtx) @@ -392,7 +413,8 @@ trait StagedWasmEvaluator extends SAIOps { val cond = Stack.popC(ty) val symCond = Stack.popS(ty) info(s"The br_if(${label})'s condition is ", cond.toInt) - ExploreTree.fillWithIfElse(symCond.s) + val id = Counter.getId(inst) + ExploreTree.fillWithIfElse(symCond.s, id) def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { trail(label)(newCtx)(mk) }) @@ -423,7 +445,8 @@ trait StagedWasmEvaluator extends SAIOps { val labelSym = Stack.peekS(ty) val cond = (label - toStagedNum(I32V(idx))).isZero() val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() - ExploreTree.fillWithIfElse(condSym.s) + val id = Counter.getId(inst) + ExploreTree.fillWithIfElse(condSym.s, id) // When moving the cursor to a branch, we mark another branch as // snapshotNode (this is done by moveCursor's runtime implementation) // TODO: store snapshot into this snapshot node @@ -622,6 +645,7 @@ trait StagedWasmEvaluator extends SAIOps { } def evalTop(mkont: Rep[MCont[Unit]], main: Option[String]): Rep[Unit] = { + Counter.reset() val funBody: FuncBodyDef = main match { case Some(func_name) => module.defs.flatMap({ @@ -912,8 +936,8 @@ trait StagedWasmEvaluator extends SAIOps { // Exploration tree, object ExploreTree { - def fillWithIfElse(s: Rep[SymVal]): Rep[Unit] = { - "tree-fill-if-else".reflectCtrlWith[Unit](s) + def fillWithIfElse(s: Rep[SymVal], id: Int): Rep[Unit] = { + "tree-fill-if-else".reflectCtrlWith[Unit](s, id) } def fillWithFinished(): Rep[Unit] = { @@ -1448,8 +1472,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("SymEnv.read("); shallow(sym); emit(")") case Node(_, "assert-true", List(cond), _) => emit("GENSYM_ASSERT("); shallow(cond); emit(")") - case Node(_, "tree-fill-if-else", List(sym), _) => - emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(")") + case Node(_, "tree-fill-if-else", List(sym, id), _) => + emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(", "); emit(id.toString); emit(")") case Node(_, "tree-fill-finished", List(), _) => emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b, snapshot), _) => @@ -1496,12 +1520,12 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emitDatastructures(stream) emitFunctions(stream) emit(src) - emitln(""" + emitln(s""" |/***************************************** |End of Generated Code |*******************************************/ |int main(int argc, char *argv[]) { - | start_concolic_execution_with(Snippet); + | start_concolic_execution_with(Snippet, ${Counter.currentId}); | return 0; |}""".stripMargin) } From 8971eb54fd9740925cc23243b38ff7233a92613e Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 3 Sep 2025 21:22:51 -0400 Subject: [PATCH 31/82] a bitmap to record the branch coverage --- headers/wasm/concolic_driver.hpp | 26 +++++++++++--------------- headers/wasm/symbolic_rt.hpp | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index e0b9e726..83252f7d 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -6,6 +6,7 @@ #include "symbolic_rt.hpp" #include "utils.hpp" #include +#include #include #include #include @@ -14,10 +15,11 @@ class ConcolicDriver { friend class ManagedConcolicCleanup; public: - ConcolicDriver(std::function entrypoint, std::string tree_file) - : entrypoint(entrypoint), tree_file(tree_file) {} - ConcolicDriver(std::function entrypoint) - : entrypoint(entrypoint), tree_file(std::nullopt) {} + ConcolicDriver(std::function entrypoint, + std::optional tree_file, int branchCount) + : entrypoint(entrypoint), tree_file(tree_file) { + ExploreTree.branch_cov_map.assign(branchCount, false); + } void run(); private: @@ -92,22 +94,16 @@ static std::monostate reset_stacks() { return std::monostate{}; } -static void start_concolic_execution_with( - std::function entrypoint, - std::string tree_file) { - ConcolicDriver driver([=]() { entrypoint(std::monostate{}); }, tree_file); - driver.run(); -} - static void start_concolic_execution_with( std::function entrypoint, int branchCount) { const char *env_tree_file = std::getenv("TREE_FILE"); - ConcolicDriver driver = - env_tree_file ? ConcolicDriver([=]() { entrypoint(std::monostate{}); }, - env_tree_file) - : ConcolicDriver([=]() { entrypoint(std::monostate{}); }); + auto tree_file = + env_tree_file ? std::make_optional(env_tree_file) : std::nullopt; + + ConcolicDriver driver = ConcolicDriver( + [=]() { entrypoint(std::monostate{}); }, tree_file, branchCount); driver.run(); } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index dfc0f7b1..1d80b037 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -291,7 +291,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond, int id); + std::monostate fillIfElseNode(SymVal cond); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -344,11 +344,10 @@ struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; - int id; - IfElseNode(SymVal cond, NodeBox *parent, int id) + IfElseNode(SymVal cond, NodeBox *parent) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)), id(id) {} + false_branch(std::make_unique(parent)) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -481,10 +480,10 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond, int id) { +inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { // fill the current NodeBox with an ifelse branch node when it's unexplored if (this->isUnexplored()) { - node = std::make_unique(cond, this, id); + node = std::make_unique(cond, this); } assert( dynamic_cast(node.get()) != nullptr && @@ -583,7 +582,8 @@ class ExploreTree_t { std::monostate fillFailedNode() { return cursor->fillFailedNode(); } std::monostate fillIfElseNode(SymVal cond, int id) { - return cursor->fillIfElseNode(cond, id); + branch_cov_map[id] = true; + return cursor->fillIfElseNode(cond); } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { @@ -637,6 +637,14 @@ class ExploreTree_t { // For now, we just iterate through the tree and return the first unexplored return pick_unexplored_of(root.get()); } + std::vector branch_cov_map; + bool all_branch_covered() const { + for (bool covered : branch_cov_map) { + if (!covered) + return false; + } + return true; + } private: NodeBox *pick_unexplored_of(NodeBox *node) { From 1b92fc0e8db85ac4b567fe121e23dd970aa178d4 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 4 Sep 2025 13:00:17 -0400 Subject: [PATCH 32/82] a new exploring strategy: exit when all branches are covered --- headers/wasm/concolic_driver.hpp | 23 +++++++++++++++-- headers/wasm/symbolic_rt.hpp | 25 ++++++++++++------- .../scala/wasm/StagedConcolicMiniWasm.scala | 20 ++++++++++----- .../genwasym/TestStagedConcolicEval.scala | 14 +++++++++-- 4 files changed, 63 insertions(+), 19 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 83252f7d..0ad21246 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -11,6 +11,16 @@ #include #include +enum class ExploreMode { EarlyExit, ExitByCoverage }; + +#ifdef EARLY_EXIT +static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; +#elif defined(BY_COVERAGE) +static const ExploreMode EXPLORE_MODE = ExploreMode::ExitByCoverage; +#else +static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; +#endif + class ConcolicDriver { friend class ManagedConcolicCleanup; @@ -18,7 +28,8 @@ class ConcolicDriver { ConcolicDriver(std::function entrypoint, std::optional tree_file, int branchCount) : entrypoint(entrypoint), tree_file(tree_file) { - ExploreTree.branch_cov_map.assign(branchCount, false); + ExploreTree.true_branch_cov_map.assign(branchCount, false); + ExploreTree.false_branch_cov_map.assign(branchCount, false); } void run(); @@ -76,7 +87,15 @@ inline void ConcolicDriver::run() { ExploreTree.fillFailedNode(); GENSYM_INFO("Caught runtime error with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); - return; + switch (EXPLORE_MODE) { + case ExploreMode::EarlyExit: + return; + case ExploreMode::ExitByCoverage: + if (ExploreTree.all_branch_covered()) { + GENSYM_INFO("All branches covered, exiting..."); + return; + } + } } #if defined(RUN_ONCE) return; diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 1d80b037..974a71c7 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -291,7 +291,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond); + std::monostate fillIfElseNode(SymVal cond, int id); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -344,10 +344,11 @@ struct IfElseNode : Node { SymVal cond; std::unique_ptr true_branch; std::unique_ptr false_branch; + int id; - IfElseNode(SymVal cond, NodeBox *parent) + IfElseNode(SymVal cond, NodeBox *parent, int id) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)) {} + false_branch(std::make_unique(parent)), id(id) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -480,10 +481,10 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond) { +inline std::monostate NodeBox::fillIfElseNode(SymVal cond, int id) { // fill the current NodeBox with an ifelse branch node when it's unexplored if (this->isUnexplored()) { - node = std::make_unique(cond, this); + node = std::make_unique(cond, this, id); } assert( dynamic_cast(node.get()) != nullptr && @@ -582,8 +583,7 @@ class ExploreTree_t { std::monostate fillFailedNode() { return cursor->fillFailedNode(); } std::monostate fillIfElseNode(SymVal cond, int id) { - branch_cov_map[id] = true; - return cursor->fillIfElseNode(cond); + return cursor->fillIfElseNode(cond, id); } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { @@ -593,9 +593,11 @@ class ExploreTree_t { if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); if (branch) { + true_branch_cov_map[if_else_node->id] = true; if_else_node->false_branch->fillSnapshotNode(snapshot); cursor = if_else_node->true_branch.get(); } else { + false_branch_cov_map[if_else_node->id] = true; if_else_node->true_branch->fillSnapshotNode(snapshot); cursor = if_else_node->false_branch.get(); } @@ -637,9 +639,14 @@ class ExploreTree_t { // For now, we just iterate through the tree and return the first unexplored return pick_unexplored_of(root.get()); } - std::vector branch_cov_map; + std::vector true_branch_cov_map; + std::vector false_branch_cov_map; bool all_branch_covered() const { - for (bool covered : branch_cov_map) { + for (bool covered : true_branch_cov_map) { + if (!covered) + return false; + } + for (bool covered : false_branch_cov_map) { if (!covered) return false; } diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 5630e18d..118b5949 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -21,22 +21,30 @@ import gensym.structure.freer.Explore object Counter { var currentId: Int = 0 - private val dict = new HashMap[WIR, Int]() + + // WIR is the branch's corresponding ast, while the Int stands for the nth + // branch of the AST(a WIR may contain multiple branches, e.g., br_table) + private val dict = new HashMap[(WIR, Int), Int]() def reset(): Unit = { currentId = 0 dict.clear() } - def getId(wir: WIR): Int = { - if (dict.contains(wir)) { - dict(wir) + def getId(wir: WIR, nth: Int = 0): Int = { + if (dict.contains((wir, nth))) { + dict((wir, nth)) } else { val id = currentId currentId += 1 - dict(wir) = id + dict((wir, nth)) = id id } + + } + + def getId(wir: WIR): Int = { + getId(wir, 0) } } @virtualize @@ -445,7 +453,7 @@ trait StagedWasmEvaluator extends SAIOps { val labelSym = Stack.peekS(ty) val cond = (label - toStagedNum(I32V(idx))).isZero() val condSym = (labelSym - toStagedSymbolicNum(I32V(idx))).isZero() - val id = Counter.getId(inst) + val id = Counter.getId(inst, idx) ExploreTree.fillWithIfElse(condSym.s, id) // When moving the cursor to a branch, we mark another branch as // snapshotNode (this is done by moveCursor's runtime implementation) diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 5a77f58d..0e0019ee 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -9,12 +9,14 @@ import gensym.wasm.parser._ import gensym.wasm.stagedconcolicminiwasm._ class TestStagedConcolicEval extends FunSuite { - def testFileConcolicCpp(filename: String, main: Option[String] = None) = { + def testFileConcolicCpp(filename: String, + main: Option[String] = None, + exitByCoverage: Boolean = false) = { val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" val exe = s"$cppFile.exe" val exploreTreeFile = s"$filename.tree.dot" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true) + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") import sys.process._ val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! @@ -52,6 +54,14 @@ class TestStagedConcolicEval extends FunSuite { testFileConcolicCpp("./benchmarks/wasm/staged/brtable_concolic.wat") } + test("bug-finding-cov-concolic") { + testFileConcolicCpp("./benchmarks/wasm/branch-strip-buggy.wat", Some("real_main"), exitByCoverage=true) + } + + test("brtable-bug-finding-cov-concolic") { + testFileConcolicCpp("./benchmarks/wasm/staged/brtable_concolic.wat", exitByCoverage=true) + } + test("return-poly - concrete") { testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) } From 0f7ca5a5ea02d870147f6e3b23dfc2c576e5419d Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 7 Sep 2025 16:25:15 -0400 Subject: [PATCH 33/82] support numeric globals --- benchmarks/wasm/staged/simple_global.wat | 22 +++++++++++++ headers/wasm/concolic_driver.hpp | 2 ++ headers/wasm/concrete_rt.hpp | 1 + headers/wasm/symbolic_rt.hpp | 1 + .../scala/wasm/StagedConcolicMiniWasm.scala | 32 +++++++++++++++++-- .../genwasym/TestStagedConcolicEval.scala | 4 +++ 6 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 benchmarks/wasm/staged/simple_global.wat diff --git a/benchmarks/wasm/staged/simple_global.wat b/benchmarks/wasm/staged/simple_global.wat new file mode 100644 index 00000000..4877f42c --- /dev/null +++ b/benchmarks/wasm/staged/simple_global.wat @@ -0,0 +1,22 @@ +(module $simple_global + (type (;0;) (func (param i32 i32) (result i32))) + (type (;1;) (func (result i32))) + (type (;2;) (func (param i32))) + (func $real_main (type 1) (result i32) + (local i32) + i32.const 0 + i32.symbolic + local.tee 0 + local.get 0 + global.set 0 + if + else + i32.const 0 + call 1 + end) + (import "console" "assert" (func (type 2))) + (memory (;0;) 16) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "real_main" (func 0))) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 0ad21246..81b5d5ad 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -94,6 +94,8 @@ inline void ConcolicDriver::run() { if (ExploreTree.all_branch_covered()) { GENSYM_INFO("All branches covered, exiting..."); return; + } else { + GENSYM_INFO("Found a bug, but not all branches covered, continuing..."); } } } diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 76c2537a..179ef245 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -181,6 +181,7 @@ class Frames_t { }; static Frames_t Frames; +static Frames_t Globals; static void initRand() { // for now, just do nothing diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 974a71c7..137d071d 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -283,6 +283,7 @@ inline void SymFrames_t::reuse(Snapshot_t snapshot) { } static SymFrames_t SymFrames; +static SymFrames_t SymGlobals; struct Node; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 118b5949..a4958e27 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -679,6 +679,7 @@ trait StagedWasmEvaluator extends SAIOps { } val (instrs, locals) = (funBody.body, funBody.locals) resetStacks() + initGlobals(module.globals) Frames.pushFrameC(locals) Frames.pushFrameS(locals) eval(instrs, (_: Context) => forwardKont, mkont, ((_: Context) => forwardKont)::Nil)(Context(Nil, locals)) @@ -883,6 +884,18 @@ trait StagedWasmEvaluator extends SAIOps { "reset-stacks".reflectCtrlWith[Unit]() } + def initGlobals(globals: List[RTGlobal]): Rep[Unit] = { + Globals.reserveSpace(globals.size) + for ((g, i) <- globals.view.zipWithIndex) { + val initValue = g.value match { + case n: Num => n + case _ => throw new RuntimeException("Non-numeric global value is not supported yet") + } + Globals.setC(i, toStagedNum(initValue)) + Globals.setS(i, toStagedSymbolicNum(initValue)) + } + } + // call unreachable def unreachable(): Rep[Unit] = { "unreachable".reflectCtrlWith[Unit]() @@ -905,6 +918,11 @@ trait StagedWasmEvaluator extends SAIOps { // global read/write object Globals { + def reserveSpace(size: Int): Rep[Unit] = { + "global-reserve".reflectCtrlWith[Unit](size) + "sym-global-reserve".reflectCtrlWith[Unit](size) + } + def getC(i: Int): StagedConcreteNum = { module.globals(i).ty match { case GlobalType(NumType(I32Type), _) => I32C("global-get".reflectCtrlWith[Num](i)) @@ -1352,8 +1370,6 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Frames.set("); shallow(i); emit(", "); shallow(value); emit(");\n") case Node(_, "sym-frame-set", List(i, s_value), _) => emit("SymFrames.set("); shallow(i); emit(", "); shallow(s_value); emit(");\n") - case Node(_, "global-set", List(i, value), _) => - emit("Global.globalSet("); shallow(i); emit(", "); shallow(value); emit(");\n") // Note: The following code is copied from the traverse of CppBackend.scala, try to avoid duplicated code case n @ Node(f, "λ", (b: LMSBlock)::LMSConst(0)::rest, _) => // TODO: Is a leading block followed by 0 a hint for top function? @@ -1410,7 +1426,17 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "stack-size", _, _) => emit("Stack.size()") case Node(_, "global-get", List(i), _) => - emit("Global.globalGet("); shallow(i); emit(")") + emit("Globals.get("); shallow(i); emit(")") + case Node(_, "sym-global-get", List(i), _) => + emit("SymGlobal.get("); shallow(i); emit(")") + case Node(_, "global-set", List(i, value), _) => + emit("Globals.set("); shallow(i); emit(", "); shallow(value); emit(")") + case Node(_, "sym-global-set", List(i, s_value), _) => + emit("SymGlobals.set("); shallow(i); emit(", "); shallow(s_value); emit(")") + case Node(_, "global-reserve", List(i), _) => + emit("Globals.pushFrame("); shallow(i); emit(")") + case Node(_, "sym-global-reserve", List(i), _) => + emit("SymGlobals.pushFrame("); shallow(i); emit(")") case Node(_, "is-zero", List(num), _) => emit("(0 == "); shallow(num); emit(")") case Node(_, "sym-is-zero", List(s_num), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 0e0019ee..303a3fe5 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -62,6 +62,10 @@ class TestStagedConcolicEval extends FunSuite { testFileConcolicCpp("./benchmarks/wasm/staged/brtable_concolic.wat", exitByCoverage=true) } + test("simple-global-bug-finding-cov-concolic") { + testFileConcolicCpp("./benchmarks/wasm/staged/simple_global.wat", Some("real_main"), exitByCoverage=true) + } + test("return-poly - concrete") { testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) } From 0fded4c6f34c1b16b10a3779ad42aa4675cfcc41 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 8 Sep 2025 20:00:47 -0400 Subject: [PATCH 34/82] Explicitly classify the next stage computation and its type Then we can compose/decompose them more easily. --- .../scala/wasm/StagedConcolicMiniWasm.scala | 596 +++++++++--------- 1 file changed, 288 insertions(+), 308 deletions(-) diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index a4958e27..aee63cda 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -51,60 +51,26 @@ object Counter { trait StagedWasmEvaluator extends SAIOps { def module: ModuleInstance - trait ReturnSite + case class StagedConcreteNum(tipe: ValueType, i: Rep[Num]) - trait StagedNum { - def tipe: ValueType - } - - trait StagedConcreteNum { - def tipe: ValueType = this match { - case I32C(_) => NumType(I32Type) - case I64C(_) => NumType(I64Type) - case F32C(_) => NumType(F32Type) - case F64C(_) => NumType(F64Type) - } - - def i: Rep[Num] - } - - case class I32C(i: Rep[Num]) extends StagedConcreteNum - case class I64C(i: Rep[Num]) extends StagedConcreteNum - case class F32C(i: Rep[Num]) extends StagedConcreteNum - case class F64C(i: Rep[Num]) extends StagedConcreteNum - - trait StagedSymbolicNum { - def tipe: ValueType = this match { - case I32S(_) => NumType(I32Type) - case I64S(_) => NumType(I64Type) - case F32S(_) => NumType(F32Type) - case F64S(_) => NumType(F64Type) - } - - def s: Rep[SymVal] - } - - case class I32S(s: Rep[SymVal]) extends StagedSymbolicNum - case class I64S(s: Rep[SymVal]) extends StagedSymbolicNum - case class F32S(s: Rep[SymVal]) extends StagedSymbolicNum - case class F64S(s: Rep[SymVal]) extends StagedSymbolicNum + case class StagedSymbolicNum(tipe: ValueType, s: Rep[SymVal]) def toStagedNum(num: Num): StagedConcreteNum = { num match { - case I32V(_) => I32C(num) - case I64V(_) => I64C(num) - case F32V(_) => F32C(num) - case F64V(_) => F64C(num) + case I32V(_) => StagedConcreteNum(NumType(I32Type), num) + case I64V(_) => StagedConcreteNum(NumType(I64Type), num) + case F32V(_) => StagedConcreteNum(NumType(F32Type), num) + case F64V(_) => StagedConcreteNum(NumType(F64Type), num) } } def toStagedSymbolicNum(num: Num): StagedSymbolicNum = { num match { - case I32V(_) => I32S(Concrete(num)) - case I64V(_) => I64S(Concrete(num)) - case F32V(_) => F32S(Concrete(num)) - case F64V(_) => F64S(Concrete(num)) + case I32V(_) => StagedSymbolicNum(NumType(I32Type), Concrete(num)) + case I64V(_) => StagedSymbolicNum(NumType(I64Type), Concrete(num)) + case F32V(_) => StagedSymbolicNum(NumType(F32Type), Concrete(num)) + case F64V(_) => StagedSymbolicNum(NumType(F64Type), Concrete(num)) } } @@ -115,24 +81,6 @@ trait StagedWasmEvaluator extends SAIOps { case NumType(F32Type) => 4 case NumType(F64Type) => 8 } - - def concreteTag: (Rep[Num]) => StagedConcreteNum = { - ty match { - case NumType(I32Type) => I32C - case NumType(I64Type) => I64C - case NumType(F32Type) => F32C - case NumType(F64Type) => F64C - } - } - - def symbolicTag: (Rep[SymVal]) => StagedSymbolicNum = { - ty match { - case NumType(I32Type) => I32S - case NumType(I64Type) => I64S - case NumType(F32Type) => F32S - case NumType(F64Type) => F64S - } - } } case class Context( @@ -225,7 +173,7 @@ trait StagedWasmEvaluator extends SAIOps { val id = Stack.popS(ty) val symVal = id.makeSymbolic(ty) val num = SymEnv.read(symVal.s) - Stack.pushC(ty.concreteTag(num)) + Stack.pushC(StagedConcreteNum(ty, num)) Stack.pushS(symVal) val newCtx = ctx.pop()._2.push(ty) eval(rest, kont, mkont, trail)(newCtx) @@ -295,8 +243,8 @@ trait StagedWasmEvaluator extends SAIOps { // For now, we assume that the result of memory.grow only depends on the execution path, // we can relax this by turning it return to a symbol value and mimic the memory.grow's result as input. val retSym = "Concrete".reflectCtrlWith[SymVal](retNum) - Stack.pushC(I32C(retNum)) - Stack.pushS(I32S(retSym)) + Stack.pushC(StagedConcreteNum(NumType(I32Type), retNum)) + Stack.pushS(StagedSymbolicNum(NumType(I32Type), retSym)) val newCtx2 = ctx.push(NumType(I32Type)) eval(rest, kont, mkont, trail)(newCtx2) case MemoryFill => ??? @@ -722,47 +670,25 @@ trait StagedWasmEvaluator extends SAIOps { "stack-init".reflectCtrlWith[Unit]() } - def popC(ty: ValueType): StagedConcreteNum = ty match { - case NumType(I32Type) => I32C("stack-pop".reflectCtrlWith[Num]()) - case NumType(I64Type) => I64C("stack-pop".reflectCtrlWith[Num]()) - case NumType(F32Type) => F32C("stack-pop".reflectCtrlWith[Num]()) - case NumType(F32Type) => F64C("stack-pop".reflectCtrlWith[Num]()) + def popC(ty: ValueType): StagedConcreteNum = { + StagedConcreteNum(ty, "stack-pop".reflectCtrlWith[Num]()) } - def popS(ty: ValueType): StagedSymbolicNum = ty match { - case NumType(I32Type) => I32S("sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(I64Type) => I64S("sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F32S("sym-stack-pop".reflectCtrlWith[SymVal]()) - case NumType(F64Type) => F64S("sym-stack-pop".reflectCtrlWith[SymVal]()) + def popS(ty: ValueType): StagedSymbolicNum = { + StagedSymbolicNum(ty, "sym-stack-pop".reflectCtrlWith[SymVal]()) } - def peekC(ty: ValueType): StagedConcreteNum = ty match { - case NumType(I32Type) => I32C("stack-peek".reflectCtrlWith[Num]()) - case NumType(I64Type) => I64C("stack-peek".reflectCtrlWith[Num]()) - case NumType(F32Type) => F32C("stack-peek".reflectCtrlWith[Num]()) - case NumType(F32Type) => F64C("stack-peek".reflectCtrlWith[Num]()) + def peekC(ty: ValueType): StagedConcreteNum = { + StagedConcreteNum(ty, "stack-peek".reflectCtrlWith[Num]()) } - def peekS(ty: ValueType): StagedSymbolicNum = ty match { - case NumType(I32Type) => I32S("sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(I64Type) => I64S("sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(F32Type) => F32S("sym-stack-peek".reflectCtrlWith[SymVal]()) - case NumType(F64Type) => F64S("sym-stack-peek".reflectCtrlWith[SymVal]()) + def peekS(ty: ValueType): StagedSymbolicNum = { + StagedSymbolicNum(ty, "sym-stack-peek".reflectCtrlWith[SymVal]()) } - def pushC(num: StagedConcreteNum) = num match { - case I32C(v) => "stack-push".reflectCtrlWith[Unit](v) - case I64C(v) => "stack-push".reflectCtrlWith[Unit](v) - case F32C(v) => "stack-push".reflectCtrlWith[Unit](v) - case F64C(v) => "stack-push".reflectCtrlWith[Unit](v) - } + def pushC(num: StagedConcreteNum) = "stack-push".reflectCtrlWith[Unit](num.i) - def pushS(num: StagedSymbolicNum) = num match { - case I32S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) - case I64S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) - case F32S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) - case F64S(s) => "sym-stack-push".reflectCtrlWith[Unit](s) - } + def pushS(num: StagedSymbolicNum) = "sym-stack-push".reflectCtrlWith[Unit](num.s) def takeC(types: List[ValueType]): List[StagedConcreteNum] = types match { case Nil => Nil @@ -792,39 +718,19 @@ trait StagedWasmEvaluator extends SAIOps { object Frames { def getC(i: Int)(implicit ctx: Context): StagedConcreteNum = { // val offset = ctx.frameTypes.take(i).map(_.size).sum - ctx.frameTypes(i) match { - case NumType(I32Type) => I32C("frame-get".reflectCtrlWith[Num](i)) - case NumType(I64Type) => I64C("frame-get".reflectCtrlWith[Num](i)) - case NumType(F32Type) => F32C("frame-get".reflectCtrlWith[Num](i)) - case NumType(F64Type) => F64C("frame-get".reflectCtrlWith[Num](i)) - } + StagedConcreteNum(ctx.frameTypes(i), "frame-get".reflectCtrlWith[Num](i)) } def getS(i: Int)(implicit ctx: Context): StagedSymbolicNum = { - ctx.frameTypes(i) match { - case NumType(I32Type) => I32S("sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(I64Type) => I64S("sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(F32Type) => F32S("sym-frame-get".reflectCtrlWith[SymVal](i)) - case NumType(F64Type) => F64S("sym-frame-get".reflectCtrlWith[SymVal](i)) - } + StagedSymbolicNum(ctx.frameTypes(i), "sym-frame-get".reflectCtrlWith[SymVal](i)) } def setC(i: Int, v: StagedConcreteNum): Rep[Unit] = { - v match { - case I32C(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case I64C(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case F32C(v) => "frame-set".reflectCtrlWith[Unit](i, v) - case F64C(v) => "frame-set".reflectCtrlWith[Unit](i, v) - } + "frame-set".reflectCtrlWith[Unit](i, v.i) } def setS(i: Int, s: StagedSymbolicNum): Rep[Unit] = { - s match { - case I32S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) - case I64S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) - case F32S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) - case F64S(s) => "sym-frame-set".reflectCtrlWith[Unit](i, s) - } + "sym-frame-set".reflectCtrlWith[Unit](i, s.s) } def pushFrameC(locals: List[ValueType]): Rep[Unit] = { @@ -867,11 +773,11 @@ trait StagedWasmEvaluator extends SAIOps { } def loadIntC(base: Rep[Int], offset: Int): StagedConcreteNum = { - I32C("I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset))) + StagedConcreteNum(NumType(I32Type), "I32V".reflectCtrlWith[Num]("memory-load-int".reflectCtrlWith[Int](base, offset))) } def loadIntS(base: Rep[Int], offset: Int): StagedSymbolicNum = { - I32S("sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) + StagedSymbolicNum(NumType(I32Type), "sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) } // Returns the previous memory size on success, or -1 if the memory cannot be grown. @@ -924,43 +830,23 @@ trait StagedWasmEvaluator extends SAIOps { } def getC(i: Int): StagedConcreteNum = { - module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => I32C("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(I64Type), _) => I64C("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(F32Type), _) => F32C("global-get".reflectCtrlWith[Num](i)) - case GlobalType(NumType(F64Type), _) => F64C("global-get".reflectCtrlWith[Num](i)) - } + StagedConcreteNum(module.globals(i).ty.ty, "global-get".reflectCtrlWith[Num](i)) } def getS(i: Int): StagedSymbolicNum = { - module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => I32S("sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(I64Type), _) => I64S("sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(F32Type), _) => F32S("sym-global-get".reflectCtrlWith[SymVal](i)) - case GlobalType(NumType(F64Type), _) => F64S("sym-global-get".reflectCtrlWith[SymVal](i)) - } + StagedSymbolicNum(module.globals(i).ty.ty, "sym-global-get".reflectCtrlWith[SymVal](i)) } def setC(i: Int, v: StagedConcreteNum): Rep[Unit] = { - module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) - case GlobalType(NumType(I64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) - case GlobalType(NumType(F32Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) - case GlobalType(NumType(F64Type), _) => "global-set".reflectCtrlWith[Unit](i, v.i) - } + "global-set".reflectCtrlWith[Unit](i, v.i) } def setS(i: Int, s: StagedSymbolicNum): Rep[Unit] = { - module.globals(i).ty match { - case GlobalType(NumType(I32Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) - case GlobalType(NumType(I64Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) - case GlobalType(NumType(F32Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) - case GlobalType(NumType(F64Type), _) => "sym-global-set".reflectCtrlWith[Unit](i, s.s) - } + "sym-global-set".reflectCtrlWith[Unit](i, s.s) } } - // Exploration tree, + // Exploration tree, object ExploreTree { def fillWithIfElse(s: Rep[SymVal], id: Int): Rep[Unit] = { "tree-fill-if-else".reflectCtrlWith[Unit](s, id) @@ -993,320 +879,414 @@ trait StagedWasmEvaluator extends SAIOps { // runtime Num type implicit class StagedConcreteNumOps(num: StagedConcreteNum) { - def makeSymbolic(ty: ValueType): StagedSymbolicNum = num match { - case I32C(x) => I32S("make-symbolic-concrete".reflectCtrlWith[SymVal](num.toInt)) + def makeSymbolic(ty: ValueType): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => + StagedSymbolicNum(NumType(I32Type), "make-symbolic-concrete".reflectCtrlWith[SymVal](num.toInt)) } def toInt: Rep[Int] = "num-to-int".reflectCtrlWith[Int](num.i) - def isZero(): StagedConcreteNum = num match { - case I32C(x_c) => I32C(Values.I32V("is-zero".reflectCtrlWith[Int](num.toInt))) + def isZero(): StagedConcreteNum = num.tipe match { + case NumType(I32Type) => + StagedConcreteNum(NumType(I32Type), Values.I32V("is-zero".reflectCtrlWith[Int](num.toInt))) } - def clz(): StagedConcreteNum = num match { - case I32C(x) => I32C("clz".reflectCtrlWith[Num](x)) - case I64C(x) => I64C("clz".reflectCtrlWith[Num](x)) + def clz(): StagedConcreteNum = num.tipe match { + case NumType(I32Type) => StagedConcreteNum(NumType(I32Type), "clz".reflectCtrlWith[Num](num.i)) + case NumType(I64Type) => StagedConcreteNum(NumType(I64Type), "clz".reflectCtrlWith[Num](num.i)) } - def ctz(): StagedConcreteNum = num match { - case I32C(x) => I32C("ctz".reflectCtrlWith[Num](x)) - case I64C(x) => I64C("ctz".reflectCtrlWith[Num](x)) + def ctz(): StagedConcreteNum = num.tipe match { + case NumType(I32Type) => StagedConcreteNum(NumType(I32Type), "ctz".reflectCtrlWith[Num](num.i)) + case NumType(I64Type) => StagedConcreteNum(NumType(I64Type), "ctz".reflectCtrlWith[Num](num.i)) } - def popcnt(): StagedConcreteNum = num match { - case I32C(x) => I32C("popcnt".reflectCtrlWith[Num](x)) - case I64C(x) => I64C("popcnt".reflectCtrlWith[Num](x)) + def popcnt(): StagedConcreteNum = num.tipe match { + case NumType(I32Type) => StagedConcreteNum(NumType(I32Type), "popcnt".reflectCtrlWith[Num](num.i)) + case NumType(I64Type) => StagedConcreteNum(NumType(I64Type), "popcnt".reflectCtrlWith[Num](num.i)) } - def +(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-add".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-add".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-add".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-add".reflectCtrlWith[Num](x, y)) - } + def +(rhs: StagedConcreteNum): StagedConcreteNum = (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-add".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-add".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-add".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-add".reflectCtrlWith[Num](num.i, rhs.i)) } - def -(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-sub".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-sub".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-sub".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-sub".reflectCtrlWith[Num](x, y)) - } + def -(rhs: StagedConcreteNum): StagedConcreteNum = (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-sub".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-sub".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-sub".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-sub".reflectCtrlWith[Num](num.i, rhs.i)) } def *(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-mul".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-mul".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-mul".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-mul".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-mul".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-mul".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-mul".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-mul".reflectCtrlWith[Num](num.i, rhs.i)) } } def /(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-div".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-div".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-div".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-div".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-div".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-div".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-div".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-div".reflectCtrlWith[Num](num.i, rhs.i)) } } def <<(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-shl".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-shl".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-shl".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-shl".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-shl".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-shl".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-shl".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-shl".reflectCtrlWith[Num](num.i, rhs.i)) } } def >>(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-shr".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-shr".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-shr".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-shr".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-shr".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-shr".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-shr".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-shr".reflectCtrlWith[Num](num.i, rhs.i)) } } def &(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("binary-and".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I64C("binary-and".reflectCtrlWith[Num](x, y)) - case (F32C(x), F32C(y)) => F32C("binary-and".reflectCtrlWith[Num](x, y)) - case (F64C(x), F64C(y)) => F64C("binary-and".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "binary-and".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I64Type), "binary-and".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F32Type), NumType(F32Type)) => + StagedConcreteNum(NumType(F32Type), "binary-and".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(F64Type), NumType(F64Type)) => + StagedConcreteNum(NumType(F64Type), "binary-and".reflectCtrlWith[Num](num.i, rhs.i)) } } def numEq(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-eq".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-eq".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-eq".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-eq".reflectCtrlWith[Num](num.i, rhs.i)) } } def numNe(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-ne".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-ne".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ne".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ne".reflectCtrlWith[Num](num.i, rhs.i)) } } def <(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-lt".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-lt".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-lt".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-lt".reflectCtrlWith[Num](num.i, rhs.i)) } } def ltu(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-ltu".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-ltu".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ltu".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ltu".reflectCtrlWith[Num](num.i, rhs.i)) } } def >(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-gt".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-gt".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-gt".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-gt".reflectCtrlWith[Num](num.i, rhs.i)) } } def gtu(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-gtu".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-gtu".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-gtu".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-gtu".reflectCtrlWith[Num](num.i, rhs.i)) } } def <=(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-le".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-le".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-le".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-le".reflectCtrlWith[Num](num.i, rhs.i)) } } def leu(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-leu".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-leu".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-leu".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-leu".reflectCtrlWith[Num](num.i, rhs.i)) } } def >=(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-ge".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-ge".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ge".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-ge".reflectCtrlWith[Num](num.i, rhs.i)) } } def geu(rhs: StagedConcreteNum): StagedConcreteNum = { - (num, rhs) match { - case (I32C(x), I32C(y)) => I32C("relation-geu".reflectCtrlWith[Num](x, y)) - case (I64C(x), I64C(y)) => I32C("relation-geu".reflectCtrlWith[Num](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedConcreteNum(NumType(I32Type), "relation-geu".reflectCtrlWith[Num](num.i, rhs.i)) + case (NumType(I64Type), NumType(I64Type)) => + StagedConcreteNum(NumType(I32Type), "relation-geu".reflectCtrlWith[Num](num.i, rhs.i)) } } } implicit class StagedSymbolicNumOps(num: StagedSymbolicNum) { - def makeSymbolic(ty: ValueType): StagedSymbolicNum = num match { - case I32S(x) => I32S("make-symbolic".reflectCtrlWith[SymVal](x)) + def makeSymbolic(ty: ValueType): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => StagedSymbolicNum(NumType(I32Type), "make-symbolic".reflectCtrlWith[SymVal](num.s)) case _ => throw new RuntimeException("Symbol index must be an i32") } - def isZero(): StagedSymbolicNum = num match { - case I32S(x) => I32S("sym-is-zero".reflectCtrlWith[SymVal](x)) + def isZero(): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => StagedSymbolicNum(NumType(I32Type), "sym-is-zero".reflectCtrlWith[SymVal](num.s)) } - def clz(): StagedSymbolicNum = num match { - case I32S(x) => I32S("sym-clz".reflectCtrlWith[SymVal](x)) - case I64S(x) => I64S("sym-clz".reflectCtrlWith[SymVal](x)) + def clz(): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => StagedSymbolicNum(NumType(I32Type), "sym-clz".reflectCtrlWith[SymVal](num.s)) + case NumType(I64Type) => StagedSymbolicNum(NumType(I64Type), "sym-clz".reflectCtrlWith[SymVal](num.s)) } - def ctz(): StagedSymbolicNum = num match { - case I32S(x) => I32S("sym-ctz".reflectCtrlWith[SymVal](x)) - case I64S(x) => I64S("sym-ctz".reflectCtrlWith[SymVal](x)) + def ctz(): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => StagedSymbolicNum(NumType(I32Type), "sym-ctz".reflectCtrlWith[SymVal](num.s)) + case NumType(I64Type) => StagedSymbolicNum(NumType(I64Type), "sym-ctz".reflectCtrlWith[SymVal](num.s)) } - def popcnt(): StagedSymbolicNum = num match { - case I32S(x) => I32S("sym-popcnt".reflectCtrlWith[SymVal](x)) - case I64S(x) => I64S("sym-popcnt".reflectCtrlWith[SymVal](x)) + def popcnt(): StagedSymbolicNum = num.tipe match { + case NumType(I32Type) => StagedSymbolicNum(NumType(I32Type), "sym-popcnt".reflectCtrlWith[SymVal](num.s)) + case NumType(I64Type) => StagedSymbolicNum(NumType(I64Type), "sym-popcnt".reflectCtrlWith[SymVal](num.s)) } def +(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-add".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-add".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-add".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-add".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-add".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def -(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-sub".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-sub".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-sub".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-sub".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-sub".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def *(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-mul".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-mul".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-mul".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-mul".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-mul".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def /(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-div".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-div".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-div".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-div".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-div".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def <<(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-shl".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-shl".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-shl".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-shl".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-shl".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def >>(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-shr".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-shr".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-shr".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-shr".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-shr".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def &(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I64S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) - case (F32S(x), F32S(y)) => F32S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) - case (F64S(x), F64S(y)) => F64S("sym-binary-and".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-binary-and".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I64Type), "sym-binary-and".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F32Type), NumType(F32Type)) => + StagedSymbolicNum(NumType(F32Type), "sym-binary-and".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(F64Type), NumType(F64Type)) => + StagedSymbolicNum(NumType(F64Type), "sym-binary-and".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def numEq(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-eq".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-eq".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-eq".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-eq".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def numNe(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-ne".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-ne".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-ne".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-ne".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def <(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-lt".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-lt".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-lt".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-lt".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def ltu(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("relation-ltu".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("relation-ltu".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "relation-ltu".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "relation-ltu".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def >(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-gt".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-gt".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-gt".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-gt".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def gtu(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-gtu".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-gtu".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-gtu".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-gtu".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def <=(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-le".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-le".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-le".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-le".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def leu(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-leu".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-leu".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-leu".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-leu".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def >=(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-ge".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-ge".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-ge".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-ge".reflectCtrlWith[SymVal](num.s, rhs.s)) } } def geu(rhs: StagedSymbolicNum): StagedSymbolicNum = { - (num, rhs) match { - case (I32S(x), I32S(y)) => I32S("sym-relation-geu".reflectCtrlWith[SymVal](x, y)) - case (I64S(x), I64S(y)) => I32S("sym-relation-geu".reflectCtrlWith[SymVal](x, y)) + (num.tipe, rhs.tipe) match { + case (NumType(I32Type), NumType(I32Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-geu".reflectCtrlWith[SymVal](num.s, rhs.s)) + case (NumType(I64Type), NumType(I64Type)) => + StagedSymbolicNum(NumType(I32Type), "sym-relation-geu".reflectCtrlWith[SymVal](num.s, rhs.s)) } } } From 5656536f4e659dec0d875422bf2eb7e966816752 Mon Sep 17 00:00:00 2001 From: ahuoguo Date: Wed, 10 Sep 2025 00:12:03 -0400 Subject: [PATCH 35/82] correct behavior for global --- benchmarks/wasm/global-sym.wat | 21 +++++++++++++++++++ .../scala/wasm/StagedConcolicMiniWasm.scala | 2 +- .../genwasym/TestStagedConcolicEval.scala | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 benchmarks/wasm/global-sym.wat diff --git a/benchmarks/wasm/global-sym.wat b/benchmarks/wasm/global-sym.wat new file mode 100644 index 00000000..54f55894 --- /dev/null +++ b/benchmarks/wasm/global-sym.wat @@ -0,0 +1,21 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (type (;2;) (func (param i32) (result i32))) + + (func (;0;) (type 2) (param i32) (result i32) + local.get 0 + global.set 0 + global.get 0 + ) + (func (;1;) (type 1) + i32.const 0 + i32.symbolic + ;; TODO Somehow this value is always 0? + call 0 + ) + (start 1) + (memory (;0;) 2) + (export "main" (func 1)) + (global (;0;) (mut i32) (i32.const 42)) +) \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index aee63cda..2c41e2eb 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -1408,7 +1408,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "global-get", List(i), _) => emit("Globals.get("); shallow(i); emit(")") case Node(_, "sym-global-get", List(i), _) => - emit("SymGlobal.get("); shallow(i); emit(")") + emit("SymGlobals.get("); shallow(i); emit(")") case Node(_, "global-set", List(i, value), _) => emit("Globals.set("); shallow(i); emit(", "); shallow(value); emit(")") case Node(_, "sym-global-set", List(i, s_value), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 303a3fe5..851ef55d 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -76,6 +76,8 @@ class TestStagedConcolicEval extends FunSuite { // TODO: Waiting more symbolic operators' implementations // test("loop - concrete") { testFileConcreteCpp("./benchmarks/wasm/loop.wat", None, expect=Some(List(10))) } test("even-odd - concrete") { testFileConcreteCpp("./benchmarks/wasm/even_odd.wat", None, expect=Some(List(1))) } + // Try global + test("global - concrete") { testFileConcreteCpp("./benchmarks/wasm/global-sym.wat", None) } // TODO: Waiting symbolic memory's implementations // test("load - concrete") { testFileConcreteCpp("./benchmarks/wasm/load.wat", None, expect=Some(List(1))) } // test("btree - concrete") { testFileConcreteCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat") } From 51544e8fd0366e9d22614c8d86f4dbc0f30773c9 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 22 Sep 2025 22:49:02 -0400 Subject: [PATCH 36/82] make log function returning std::monostate/Unit type --- headers/wasm/concrete_rt.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 179ef245..77f7588a 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -11,18 +11,20 @@ #include #include -void info() { +inline std::monostate info() { #ifdef DEBUG std::cout << std::endl; #endif + return std::monostate{}; } template -void info(const T &first, const Args &...args) { +std::monostate info(const T &first, const Args &...args) { #ifdef DEBUG std::cout << first << " "; info(args...); #endif + return std::monostate{}; } struct Num { From 4bdc93b1fde5d3a95c0c4e571fbac50df22bfefe Mon Sep 17 00:00:00 2001 From: Alex Bai Date: Wed, 24 Sep 2025 11:30:40 +0800 Subject: [PATCH 37/82] Symbolic memory (#91) * move Memory_t to symbolic * failing cases for load * correct behavior for load/store (concrete) * test offset * test concolic, currently failed * oops * symstack and stack should be consistent * added test for extract(currently failing * extract & concat * some fixes, make btree example runable * tweak --------- Co-authored-by: butterunderflow --- benchmarks/wasm/Makefile | 7 + benchmarks/wasm/load-offset.wat | 19 ++ benchmarks/wasm/load-overflow1.wat | 19 ++ benchmarks/wasm/load-overflow2.wat | 19 ++ benchmarks/wasm/load.wat | 2 +- benchmarks/wasm/mem-sym-extract.wat | 32 +++ benchmarks/wasm/mem-sym.wat | 32 +++ headers/wasm/concrete_rt.hpp | 40 +--- headers/wasm/smt_solver.hpp | 19 ++ headers/wasm/symbolic_rt.hpp | 216 ++++++++++++++++-- .../scala/wasm/StagedConcolicMiniWasm.scala | 32 ++- .../genwasym/TestStagedConcolicEval.scala | 18 +- 12 files changed, 390 insertions(+), 65 deletions(-) create mode 100644 benchmarks/wasm/Makefile create mode 100644 benchmarks/wasm/load-offset.wat create mode 100644 benchmarks/wasm/load-overflow1.wat create mode 100644 benchmarks/wasm/load-overflow2.wat create mode 100644 benchmarks/wasm/mem-sym-extract.wat create mode 100644 benchmarks/wasm/mem-sym.wat diff --git a/benchmarks/wasm/Makefile b/benchmarks/wasm/Makefile new file mode 100644 index 00000000..bad47a22 --- /dev/null +++ b/benchmarks/wasm/Makefile @@ -0,0 +1,7 @@ +.PHONY: clean + +clean: + find . -type f -name '*.cpp' -delete + find . -type f -name '*.cpp.exe' -delete + find . -type d -name '*.dSYM' -exec rm -rf {} + + find . -type f -name '*.dot' -delete diff --git a/benchmarks/wasm/load-offset.wat b/benchmarks/wasm/load-offset.wat new file mode 100644 index 00000000..1c42df1b --- /dev/null +++ b/benchmarks/wasm/load-offset.wat @@ -0,0 +1,19 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (func (;0;) (type 0) (result i32) + i32.const 0 + i32.const 256 + i32.store + i32.const 0 + i32.load offset=1 + ) + (func (;1;) (type 1) + call 0 + ;; should be 1 + ;; drop + ) + (start 1) + (memory (;0;) 2) + (export "main" (func 1)) +) \ No newline at end of file diff --git a/benchmarks/wasm/load-overflow1.wat b/benchmarks/wasm/load-overflow1.wat new file mode 100644 index 00000000..9f005ea1 --- /dev/null +++ b/benchmarks/wasm/load-overflow1.wat @@ -0,0 +1,19 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (func (;0;) (type 0) (result i32) + i32.const 0 + i32.const 256 + i32.store + i32.const 1 + i32.load + ) + (func (;1;) (type 1) + call 0 + ;; should be 1 + ;; drop + ) + (start 1) + (memory (;0;) 2) + (export "main" (func 1)) +) \ No newline at end of file diff --git a/benchmarks/wasm/load-overflow2.wat b/benchmarks/wasm/load-overflow2.wat new file mode 100644 index 00000000..86c1a574 --- /dev/null +++ b/benchmarks/wasm/load-overflow2.wat @@ -0,0 +1,19 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (func (;0;) (type 0) (result i32) + i32.const 0 + i32.const 65536 + i32.store + i32.const 2 + i32.load + ) + (func (;1;) (type 1) + call 0 + ;; should be 1 + ;; drop + ) + (start 1) + (memory (;0;) 2) + (export "main" (func 1)) +) \ No newline at end of file diff --git a/benchmarks/wasm/load.wat b/benchmarks/wasm/load.wat index 916328aa..6c43d79b 100644 --- a/benchmarks/wasm/load.wat +++ b/benchmarks/wasm/load.wat @@ -10,7 +10,7 @@ ) (func (;1;) (type 1) call 0 - ;; should be 65536 + ;; should be 1 ;; drop ) (start 1) diff --git a/benchmarks/wasm/mem-sym-extract.wat b/benchmarks/wasm/mem-sym-extract.wat new file mode 100644 index 00000000..ca7e70eb --- /dev/null +++ b/benchmarks/wasm/mem-sym-extract.wat @@ -0,0 +1,32 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (type (;2;) (func (param i32) (result i32))) + (type (;3;) (func (param i32))) + (import "console" "assert" (func (type 3))) + (func (;1;) (type 2) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; if x == 256 + i32.const 1 ;; return 1 + else + i32.const 0 + call 0 ;; assert false + i32.const 1 ;; to satisfy the type checker, this line will never be reached + end + ) + (func (;2;) (type 1) + i32.const 0 + i32.symbolic ;; call it x + call 1 + ) + (start 2) + (memory (;0;) 2) + (export "main" (func 1)) + (global (;0;) (mut i32) (i32.const 42)) +) \ No newline at end of file diff --git a/benchmarks/wasm/mem-sym.wat b/benchmarks/wasm/mem-sym.wat new file mode 100644 index 00000000..c7094008 --- /dev/null +++ b/benchmarks/wasm/mem-sym.wat @@ -0,0 +1,32 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func)) + (type (;2;) (func (param i32) (result i32))) + (type (;3;) (func (param i32))) + (import "console" "assert" (func (type 3))) + (func (;1;) (type 2) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.load + i32.const 25 + i32.eq + if (result i32) ;; if x == 25 + i32.const 1 ;; return 1 + else + i32.const 0 + call 0 ;; assert false + i32.const 1 ;; to satisfy the type checker, this line will never be reached + end + ) + (func (;2;) (type 1) + i32.const 0 + i32.symbolic ;; call it x + call 1 + ) + (start 2) + (memory (;0;) 2) + (export "main" (func 1)) + (global (;0;) (mut i32) (i32.const 42)) +) \ No newline at end of file diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 77f7588a..5d9243c4 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -76,6 +76,7 @@ class Stack_t { Num pop() { #ifdef DEBUG assert(count > 0 && "Stack underflow"); + printf("[Debug] poping from stack, size of concrete stack is: %d\n", count); #endif Num num = stack_ptr[count - 1]; count--; @@ -101,9 +102,13 @@ class Stack_t { if (size < 0) { throw std::out_of_range("Invalid size: " + std::to_string(size)); } + std::cout << "Shifting stack by offset " << offset << " and size " << size + << std::endl; + std::cout << "Current stack size: " << count << std::endl; #endif // shift last `size` of numbers forward of `offset` for (int32_t i = count - size; i < count; ++i) { + assert(i - offset >= 0); stack_ptr[i - offset] = stack_ptr[i]; } count -= offset; @@ -197,39 +202,4 @@ static std::monostate unreachable() { static int32_t pagesize = 65536; static int32_t page_count = 0; -struct Memory_t { - std::vector memory; - Memory_t(int32_t init_page_count) : memory(init_page_count * pagesize) {} - - int32_t loadInt(int32_t base, int32_t offset) { - return *reinterpret_cast(static_cast(memory.data()) + - base + offset); - } - - std::monostate storeInt(int32_t base, int32_t offset, int32_t value) { - *reinterpret_cast(static_cast(memory.data()) + base + - offset) = value; - return std::monostate{}; - } - - // grow memory by delta bytes when bytes > 0. return -1 if failed, return old - // size when success - int32_t grow(int32_t delta) { - if (delta <= 0) { - return memory.size(); - } - - try { - memory.resize(memory.size() + delta * pagesize); - auto old_page_count = page_count; - page_count += delta; - return memory.size(); - } catch (const std::bad_alloc &e) { - return -1; - } - } -}; - -static Memory_t Memory(1); // 1 page memory - #endif // WASM_CONCRETE_RT_HPP \ No newline at end of file diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 504422f7..64952bcc 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -71,6 +71,9 @@ inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) { } else if (auto concrete = std::dynamic_pointer_cast(sym_val.symptr)) { return z3_ctx.bv_val(concrete->value.value, 32); + } else if (auto smallbv = + std::dynamic_pointer_cast(sym_val.symptr)) { + return z3_ctx.bv_val(smallbv->get_value(), smallbv->get_size()); } else if (auto binary = std::dynamic_pointer_cast(sym_val.symptr)) { auto bit_width = 32; @@ -119,7 +122,23 @@ inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) { case DIV: { return left / right; } + case B_AND: { + return left & right; } + case CONCAT: { + return z3::concat(left, right); + } + default: + throw std::runtime_error("Operation not supported: " + + std::to_string(binary->op)); + } + } else if (auto extract = dynamic_cast(sym_val.symptr.get())) { + assert(extract); + int high = extract->high * 8 - 1; + int low = extract->low * 8 - 8; + auto s = build_z3_expr(extract->value); + auto res = s.extract(high, low); + return res; } throw std::runtime_error("Unsupported symbolic value type"); } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 137d071d..d7aa70ed 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -6,6 +6,7 @@ #include "utils.hpp" #include #include +#include #include #include #include @@ -48,8 +49,34 @@ class SymConcrete : public Symbolic { SymConcrete(Num num) : value(num) {} }; +class SmallBV : public Symbolic { +public: + SmallBV(int size, int64_t value) : size(size), value(value) {} + int get_size() const { return size; } + int64_t get_value() const { return value; } + +private: + int size; + int64_t value; +}; + struct SymBinary; +enum Operation { + ADD, // Addition + SUB, // Subtraction + MUL, // Multiplication + DIV, // Division + EQ, // Equal + NEQ, // Not equal + LT, // Less than + LEQ, // Less than or equal + GT, // Greater than + GEQ, // Greater than or equal + B_AND, // Bitwise AND + CONCAT, // Byte-level concatenation +}; + struct SymVal { std::shared_ptr symptr; @@ -59,7 +86,7 @@ struct SymVal { // data structure operations SymVal makeSymbolic() const; - // arithmetic operations + // bitvector arithmetic operations SymVal is_zero() const; SymVal add(const SymVal &other) const; SymVal minus(const SymVal &other) const; @@ -68,12 +95,19 @@ struct SymVal { SymVal eq(const SymVal &other) const; SymVal neq(const SymVal &other) const; SymVal lt(const SymVal &other) const; - SymVal leq(const SymVal &other) const; + SymVal le(const SymVal &other) const; SymVal gt(const SymVal &other) const; - SymVal geq(const SymVal &other) const; + SymVal ge(const SymVal &other) const; SymVal negate() const; + SymVal bitwise_and(const SymVal &other) const; + SymVal concat(const SymVal &other) const; + SymVal extract(int high, int low) const; + // TODO: add bitwise operations, and use the underlying bitvector theory bool is_concrete() const; + +private: + static SymVal make_binary(Operation op, const SymVal &lhs, const SymVal &rhs); }; static SymVal make_symbolic(int index) { @@ -84,7 +118,17 @@ inline SymVal Concrete(Num num) { return SymVal(std::make_shared(num)); } -enum Operation { ADD, SUB, MUL, DIV, EQ, NEQ, LT, LEQ, GT, GEQ }; +// Extract is different from other operations, it only has one symbolic operand, +// the other two operands are constants +// Extract from value, both high and low are inclusive byte indexes +struct SymExtract : Symbolic { + SymVal value; + int high; + int low; + + SymExtract(SymVal value, int high, int low) + : value(value), high(high), low(low) {} +}; struct SymBinary : Symbolic { Operation op; @@ -96,47 +140,70 @@ struct SymBinary : Symbolic { }; inline SymVal SymVal::add(const SymVal &other) const { - return SymVal(std::make_shared(ADD, *this, other)); + return make_binary(ADD, *this, other); } inline SymVal SymVal::minus(const SymVal &other) const { - return SymVal(std::make_shared(SUB, *this, other)); + return make_binary(SUB, *this, other); } inline SymVal SymVal::mul(const SymVal &other) const { - return SymVal(std::make_shared(MUL, *this, other)); + return make_binary(MUL, *this, other); } inline SymVal SymVal::div(const SymVal &other) const { - return SymVal(std::make_shared(DIV, *this, other)); + return make_binary(DIV, *this, other); } inline SymVal SymVal::eq(const SymVal &other) const { - return SymVal(std::make_shared(EQ, *this, other)); + return make_binary(EQ, *this, other); } inline SymVal SymVal::neq(const SymVal &other) const { - return SymVal(std::make_shared(NEQ, *this, other)); + return make_binary(NEQ, *this, other); } + inline SymVal SymVal::lt(const SymVal &other) const { - return SymVal(std::make_shared(LT, *this, other)); + return make_binary(LT, *this, other); } -inline SymVal SymVal::leq(const SymVal &other) const { - return SymVal(std::make_shared(LEQ, *this, other)); + +inline SymVal SymVal::le(const SymVal &other) const { + return make_binary(LEQ, *this, other); } + inline SymVal SymVal::gt(const SymVal &other) const { - return SymVal(std::make_shared(GT, *this, other)); + return make_binary(GT, *this, other); } -inline SymVal SymVal::geq(const SymVal &other) const { - return SymVal(std::make_shared(GEQ, *this, other)); + +inline SymVal SymVal::ge(const SymVal &other) const { + return make_binary(GEQ, *this, other); } + inline SymVal SymVal::is_zero() const { - return SymVal(std::make_shared(EQ, *this, Concrete(I32V(0)))); + return make_binary(EQ, *this, Concrete(I32V(0))); } + inline SymVal SymVal::negate() const { - return SymVal(std::make_shared(EQ, *this, Concrete(I32V(0)))); + return make_binary(EQ, *this, Concrete(I32V(0))); } +inline SymVal SymVal::concat(const SymVal &other) const { + return make_binary(CONCAT, *this, other); +} + +inline SymVal SymVal::extract(int high, int low) const { + assert(high >= low && "Invalid extract range"); + return SymVal(std::make_shared(*this, high, low)); +} + +inline SymVal SymVal::bitwise_and(const SymVal &other) const { + return make_binary(B_AND, *this, other); +} +inline SymVal SymVal::make_binary(Operation op, const SymVal &lhs, + const SymVal &rhs) { + assert(lhs.symptr != nullptr && rhs.symptr != nullptr); + return SymVal(std::make_shared(op, lhs, rhs)); +} inline SymVal SymVal::makeSymbolic() const { auto concrete = dynamic_cast(symptr.get()); if (concrete) { @@ -178,6 +245,7 @@ class SymStack_t { std::monostate shift(int32_t offset, int32_t size) { auto n = stack.size(); for (size_t i = n - size; i < n; ++i) { + assert(i - offset >= 0); stack[i - offset] = stack[i]; } stack.resize(n - offset); @@ -723,6 +791,17 @@ static SymEnv_t SymEnv; static Num eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { if (auto concrete = dynamic_cast(sym.symptr.get())) { return concrete->value; + } else if (auto extract = dynamic_cast(sym.symptr.get())) { + auto value = eval_sym_expr(extract->value, sym_env); + int high = extract->high; + int low = extract->low; + assert(high >= low && "Invalid extract range"); + int size = high - low + 1; // size in bytes + int64_t mask = (1LL << (size * 8)) - 1; + int64_t extracted_value = (value.toInt() >> (low * 8)) & mask; + return Num(I64V(extracted_value)); + } else if (auto smallbv = dynamic_cast(sym.symptr.get())) { + return Num(I64V(smallbv->get_value())); } else if (auto operation = dynamic_cast(sym.symptr.get())) { // If it's a operation, we need to evaluate it auto lhs = eval_sym_expr(operation->lhs, sym_env); @@ -744,8 +823,18 @@ static Num eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { return lhs > rhs; case GEQ: return lhs >= rhs; + case NEQ: + return lhs != rhs; + case EQ: + return lhs == rhs; + case B_AND: + return Num(I64V(lhs.value & rhs.value)); + case CONCAT: + // we must know the size of lhs and rhs in bytes to support concat + throw std::runtime_error( + "Concatenation operation not supported in evaluation"); default: - throw std::runtime_error("Operation not supported: " + + throw std::runtime_error("Operation not supported in evaluation: " + std::to_string(operation->op)); } } else if (auto symbol = dynamic_cast(sym.symptr.get())) { @@ -798,4 +887,93 @@ inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, return cont(mcont); } +struct Memory_t { + // TODO: We assign a SymVal to each byte in memory + std::vector> memory; + + Memory_t(int32_t init_page_count) : memory(init_page_count * pagesize) {} + + int32_t loadInt(int32_t base, int32_t offset) { + // just load a 4-byte integer from memory of the vector + int32_t addr = base + offset; + assert(addr + 3 < memory.size()); + int32_t result = 0; + // Little-endian: lowest byte at lowest address + for (int i = 0; i < 4; ++i) { + result |= static_cast(memory[addr + i].first) << (8 * i); + } + return result; + } + + // TODO: when loading a symval, we need to concat 4 symbolic values + // This sounds terribly bad for SMT... + // Load a 4-byte symbolic value from memory + SymVal loadSym(int32_t base, int32_t offset) { + int32_t addr = base + offset; + assert(addr + 3 < memory.size()); + SymVal s0 = memory[addr].second; + if (s0.symptr == nullptr) { + s0 = SymVal(std::make_shared(8, 0)); + } + SymVal s1 = memory[addr + 1].second; + if (s1.symptr == nullptr) { + s1 = SymVal(std::make_shared(8, 0)); + } + SymVal s2 = memory[addr + 2].second; + if (s2.symptr == nullptr) { + s2 = SymVal(std::make_shared(8, 0)); + } + SymVal s3 = memory[addr + 3].second; + if (s3.symptr == nullptr) { + s3 = SymVal(std::make_shared(8, 0)); + } + return s0.concat(s1).concat(s2).concat(s3); + } + + // Store a 4-byte symbolic value to memory + std::monostate storeSym(int32_t base, int32_t offset, SymVal value) { + int32_t addr = base + offset; + // Extract 4 bytes from that symbol + SymVal s0 = value.extract(1, 1); + SymVal s1 = value.extract(2, 2); + SymVal s2 = value.extract(3, 3); + SymVal s3 = value.extract(4, 4); + memory[addr].second = s0; + memory[addr + 1].second = s1; + memory[addr + 2].second = s2; + memory[addr + 3].second = s3; + return std::monostate{}; + } + + std::monostate storeInt(int32_t base, int32_t offset, int32_t value) { + int32_t addr = base + offset; + // Ensure we don't write out of bounds + assert(addr + 3 < memory.size()); + for (int i = 0; i < 4; ++i) { + memory[addr + i].first = static_cast((value >> (8 * i)) & 0xFF); + // Optionally, update memory[addr + i].second (SymVal) if needed + } + return std::monostate{}; + } + + // grow memory by delta bytes when bytes > 0. return -1 if failed, return old + // size when success + int32_t grow(int32_t delta) { + if (delta <= 0) { + return memory.size(); + } + + try { + memory.resize(memory.size() + delta * pagesize); + auto old_page_count = page_count; + page_count += delta; + return memory.size(); + } catch (const std::bad_alloc &e) { + return -1; + } + } +}; + +static Memory_t Memory(1); // 1 page memory + #endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 2c41e2eb..5b5ae8de 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -220,7 +220,7 @@ trait StagedWasmEvaluator extends SAIOps { val (ty2, newCtx2) = newCtx1.pop() val addr = Stack.popC(ty2) val symAddr = Stack.popS(ty2) - Memory.storeInt(addr.toInt, offset, value.toInt) + Memory.storeInt(addr.toInt, offset, (value.toInt, symValue)) eval(rest, kont, mkont, trail)(newCtx2) case Nop => eval(rest, kont, mkont, trail) case Load(LoadOp(align, offset, ty, None, None)) => @@ -245,7 +245,7 @@ trait StagedWasmEvaluator extends SAIOps { val retSym = "Concrete".reflectCtrlWith[SymVal](retNum) Stack.pushC(StagedConcreteNum(NumType(I32Type), retNum)) Stack.pushS(StagedSymbolicNum(NumType(I32Type), retSym)) - val newCtx2 = ctx.push(NumType(I32Type)) + val newCtx2 = newCtx.push(NumType(I32Type)) eval(rest, kont, mkont, trail)(newCtx2) case MemoryFill => ??? case Unreachable => unreachable() @@ -767,9 +767,11 @@ trait StagedWasmEvaluator extends SAIOps { } object Memory { - def storeInt(base: Rep[Int], offset: Int, value: Rep[Int]): Rep[Unit] = { - "memory-store-int".reflectCtrlWith[Unit](base, offset, value) - // todo: store symbolic value to memory via extract/concat operation + // TODO: why this is only one function, rather than `storeInC` and `storeInS`? + // TODO: what should the type of SymVal be? + def storeInt(base: Rep[Int], offset: Int, value: (Rep[Int], StagedSymbolicNum)): Rep[Unit] = { + "memory-store-int".reflectCtrlWith[Unit](base, offset, value._1) + "sym-store-int".reflectCtrlWith[Unit](base, offset, value._2.s) } def loadIntC(base: Rep[Int], offset: Int): StagedConcreteNum = { @@ -777,7 +779,7 @@ trait StagedWasmEvaluator extends SAIOps { } def loadIntS(base: Rep[Int], offset: Int): StagedSymbolicNum = { - StagedSymbolicNum(NumType(I32Type), "sym-load-int-todo".reflectCtrlWith[SymVal](base, offset)) + StagedSymbolicNum(NumType(I32Type), "sym-load-int".reflectCtrlWith[SymVal](base, offset)) } // Returns the previous memory size on success, or -1 if the memory cannot be grown. @@ -1405,6 +1407,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Memory.grow("); shallow(delta); emit(")") case Node(_, "stack-size", _, _) => emit("Stack.size()") + // Symbolic Memory + case Node(_, "sym-store-int", List(base, offset, s_value), _) => + emit("Memory.storeSym("); shallow(base); emit(", "); shallow(offset); emit(", "); shallow(s_value); emit(")") + case Node(_, "sym-load-int", List(base, offset), _) => + emit("Memory.loadSym("); shallow(base); emit(", "); shallow(offset); emit(")") + case Node(_, "sym-memory-grow", List(delta), _) => + emit("SymMemory.grow("); shallow(delta); emit(")") + // Globals case Node(_, "global-get", List(i), _) => emit("Globals.get("); shallow(i); emit(")") case Node(_, "sym-global-get", List(i), _) => @@ -1464,11 +1474,15 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(".mul("); shallow(rhs); emit(")") case Node(_, "sym-binary-div", List(lhs, rhs), _) => shallow(lhs); emit(".div("); shallow(rhs); emit(")") + case Node(_, "sym-binary-and", List(lhs, rhs), _) => + shallow(lhs); emit(".bitwise_and("); shallow(rhs); emit(")") case Node(_, "sym-relation-le", List(lhs, rhs), _) => - shallow(lhs); emit(".leq("); shallow(rhs); emit(")") + shallow(lhs); emit(".le("); shallow(rhs); emit(")") case Node(_, "sym-relation-leu", List(lhs, rhs), _) => shallow(lhs); emit(".leu("); shallow(rhs); emit(")") - case Node(_, "sym-relation-ge", List(lhs, rhs), _) => + case Node(_, "sym-relation-lt", List(lhs, rhs), _) => + shallow(lhs); emit(".lt("); shallow(rhs); emit(")") + case Node(_, "sym-relation-ge", List(lhs, rhs), _) => shallow(lhs); emit(".ge("); shallow(rhs); emit(")") case Node(_, "sym-relation-geu", List(lhs, rhs), _) => shallow(lhs); emit(".geu("); shallow(rhs); emit(")") @@ -1476,6 +1490,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(".eq("); shallow(rhs); emit(")") case Node(_, "sym-relation-ne", List(lhs, rhs), _) => shallow(lhs); emit(".neq("); shallow(rhs); emit(")") + case Node(_, "sym-relation-gt", List(lhs, rhs), _) => + shallow(lhs); emit(".gt("); shallow(rhs); emit(")") case Node(_, "num-to-int", List(num), _) => shallow(num); emit(".toInt()") case Node(_, "make-symbolic", List(num), _) => diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 851ef55d..03a5df09 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -66,6 +66,16 @@ class TestStagedConcolicEval extends FunSuite { testFileConcolicCpp("./benchmarks/wasm/staged/simple_global.wat", Some("real_main"), exitByCoverage=true) } + test("mem-sym-concolic") { + testFileConcolicCpp("./benchmarks/wasm/mem-sym.wat", None, exitByCoverage=true) + } + + test("mem-sym-extract-concolic") { + testFileConcolicCpp("./benchmarks/wasm/mem-sym-extract.wat", None, exitByCoverage=true) + } + test("btree-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat") } + + test("return-poly - concrete") { testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) } @@ -76,10 +86,14 @@ class TestStagedConcolicEval extends FunSuite { // TODO: Waiting more symbolic operators' implementations // test("loop - concrete") { testFileConcreteCpp("./benchmarks/wasm/loop.wat", None, expect=Some(List(10))) } test("even-odd - concrete") { testFileConcreteCpp("./benchmarks/wasm/even_odd.wat", None, expect=Some(List(1))) } - // Try global test("global - concrete") { testFileConcreteCpp("./benchmarks/wasm/global-sym.wat", None) } // TODO: Waiting symbolic memory's implementations - // test("load - concrete") { testFileConcreteCpp("./benchmarks/wasm/load.wat", None, expect=Some(List(1))) } + test("load - concrete") { testFileConcreteCpp("./benchmarks/wasm/load.wat", None, expect=Some(List(1))) } + test("load overflow 1 - concrete") { testFileConcreteCpp("./benchmarks/wasm/load-overflow1.wat", None, expect=Some(List(1))) } + test("load overflow 2 - concrete") { testFileConcreteCpp("./benchmarks/wasm/load-overflow2.wat", None, expect=Some(List(1))) } + + test("load offset - concrete") { testFileConcreteCpp("./benchmarks/wasm/load-offset.wat", None, expect=Some(List(1))) } + // test("btree - concrete") { testFileConcreteCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat") } test("fib - concrete") { testFileConcreteCpp("./benchmarks/wasm/fib.wat", None, expect=Some(List(144))) } test("tribonacci - concrete") { testFileConcreteCpp("./benchmarks/wasm/tribonacci.wat", None, expect=Some(List(504))) } From 74732ad5f4f47883a73bc57f9574c3f6724d2caa Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 24 Sep 2025 14:35:15 -0400 Subject: [PATCH 38/82] fix: high bits should be concat first --- benchmarks/wasm/mem-sym.wat | 15 +++++++++++++-- headers/wasm/symbolic_rt.hpp | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/benchmarks/wasm/mem-sym.wat b/benchmarks/wasm/mem-sym.wat index c7094008..45b9d1c3 100644 --- a/benchmarks/wasm/mem-sym.wat +++ b/benchmarks/wasm/mem-sym.wat @@ -13,11 +13,22 @@ i32.const 25 i32.eq if (result i32) ;; if x == 25 - i32.const 1 ;; return 1 - else i32.const 0 call 0 ;; assert false i32.const 1 ;; to satisfy the type checker, this line will never be reached + else + i32.const 1 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; if x >> 8 == 1 + i32.const 0 + call 0 ;; assert false + i32.const 1 ;; to satisfy the type checker, this line will never be reached + else + i32.const 1 + end + i32.const 1 end ) (func (;2;) (type 1) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index d7aa70ed..4c69f73b 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -927,7 +927,7 @@ struct Memory_t { if (s3.symptr == nullptr) { s3 = SymVal(std::make_shared(8, 0)); } - return s0.concat(s1).concat(s2).concat(s3); + return s3.concat(s2).concat(s1).concat(s0); } // Store a 4-byte symbolic value to memory From e3f8488e4aa2841d7fedd71d6592e18d0b875626 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 28 Sep 2025 20:49:02 -0400 Subject: [PATCH 39/82] make btree example work with concolic execution --- benchmarks/wasm/btree/2o1u-unlabeled.wat | 5 +- headers/wasm/concolic_driver.hpp | 4 +- headers/wasm/symbolic_rt.hpp | 94 ++++++++++++------- .../genwasym/TestStagedConcolicEval.scala | 2 +- 4 files changed, 68 insertions(+), 37 deletions(-) diff --git a/benchmarks/wasm/btree/2o1u-unlabeled.wat b/benchmarks/wasm/btree/2o1u-unlabeled.wat index 096f1004..443bf5d4 100644 --- a/benchmarks/wasm/btree/2o1u-unlabeled.wat +++ b/benchmarks/wasm/btree/2o1u-unlabeled.wat @@ -2626,9 +2626,12 @@ i32.and drop) (func (;7;) (type 4) - i32.const 3 i32.const 2 + i32.symbolic i32.const 1 + i32.symbolic + i32.const 0 + i32.symbolic call 6) (memory (;0;) 2) (export "main" (func 7)) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 81b5d5ad..06b3459c 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -83,7 +84,8 @@ inline void ConcolicDriver::run() { GENSYM_INFO("Execution finished successfully with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); - } catch (...) { + } catch (std::runtime_error &e) { + std::cout << "Caught runtime error: " << e.what() << std::endl; ExploreTree.fillFailedNode(); GENSYM_INFO("Caught runtime error with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 4c69f73b..96b2f039 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -56,7 +56,7 @@ class SmallBV : public Symbolic { int64_t get_value() const { return value; } private: - int size; + int size; // in bits int64_t value; }; @@ -77,10 +77,13 @@ enum Operation { CONCAT, // Byte-level concatenation }; +static std::shared_ptr ZERO = + std::make_shared(I32V(0)); + struct SymVal { std::shared_ptr symptr; - SymVal() : symptr(nullptr) {} + SymVal() : symptr(ZERO) {} SymVal(std::shared_ptr symptr) : symptr(symptr) {} // data structure operations @@ -283,12 +286,13 @@ class SymFrames_t { SymVal get(int index) { // Get the symbolic value at the given frame index - return stack[stack.size() - 1 - index]; + auto res = stack[stack.size() - 1 - index]; + return res; } void set(int index, SymVal val) { // Set the symbolic value at the given index - // Not implemented yet + assert(val.symptr != nullptr); stack[stack.size() - 1 - index] = val; } @@ -786,61 +790,72 @@ class SymEnv_t { static SymEnv_t SymEnv; +struct EvalRes { + Num value; + int width; // in bits + EvalRes(Num value, int width) : value(value), width(width) {} +}; + // TODO: reduce the re-computation of the same symbolic expression, it's better // if it can be done by the smt solver -static Num eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { +static EvalRes eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { + assert(sym.symptr != nullptr && "Symbolic expression is null"); if (auto concrete = dynamic_cast(sym.symptr.get())) { - return concrete->value; + return EvalRes(concrete->value, 32); } else if (auto extract = dynamic_cast(sym.symptr.get())) { - auto value = eval_sym_expr(extract->value, sym_env); + auto res = eval_sym_expr(extract->value, sym_env); int high = extract->high; int low = extract->low; assert(high >= low && "Invalid extract range"); int size = high - low + 1; // size in bytes int64_t mask = (1LL << (size * 8)) - 1; - int64_t extracted_value = (value.toInt() >> (low * 8)) & mask; - return Num(I64V(extracted_value)); + int64_t extracted_value = (res.value.toInt() >> (low * 8)) & mask; + return EvalRes(Num(I64V(extracted_value)), size * 8); } else if (auto smallbv = dynamic_cast(sym.symptr.get())) { - return Num(I64V(smallbv->get_value())); + return EvalRes(Num(I64V(smallbv->get_value())), smallbv->get_size()); } else if (auto operation = dynamic_cast(sym.symptr.get())) { // If it's a operation, we need to evaluate it - auto lhs = eval_sym_expr(operation->lhs, sym_env); - auto rhs = eval_sym_expr(operation->rhs, sym_env); + auto lhs_res = eval_sym_expr(operation->lhs, sym_env); + auto rhs_res = eval_sym_expr(operation->rhs, sym_env); + auto lhs = lhs_res.value; + auto rhs = rhs_res.value; switch (operation->op) { case ADD: - return lhs + rhs; + return EvalRes(lhs + rhs, 32); case SUB: - return lhs - rhs; + return EvalRes(lhs - rhs, 32); case MUL: - return lhs * rhs; + return EvalRes(lhs * rhs, 32); case DIV: - return lhs / rhs; + return EvalRes(lhs / rhs, 32); case LT: - return lhs < rhs; + return EvalRes(lhs < rhs, 32); case LEQ: - return lhs <= rhs; + return EvalRes(lhs <= rhs, 32); case GT: - return lhs > rhs; + return EvalRes(lhs > rhs, 32); case GEQ: - return lhs >= rhs; + return EvalRes(lhs >= rhs, 32); case NEQ: - return lhs != rhs; + return EvalRes(lhs != rhs, 32); case EQ: - return lhs == rhs; + return EvalRes(lhs == rhs, 32); case B_AND: - return Num(I64V(lhs.value & rhs.value)); - case CONCAT: - // we must know the size of lhs and rhs in bytes to support concat - throw std::runtime_error( - "Concatenation operation not supported in evaluation"); + return EvalRes(Num(I64V(lhs.value & rhs.value)), 32); + case CONCAT: { + auto lhs_width = lhs_res.width; + auto rhs_width = rhs_res.width; + auto conc_value = (lhs.value << rhs_width) | (rhs.value); + auto new_width = lhs_width + rhs_width; + return EvalRes(Num(I64V(conc_value)), new_width); + } default: - throw std::runtime_error("Operation not supported in evaluation: " + - std::to_string(operation->op)); + assert(false && "Operation not supported in evaluation"); } } else if (auto symbol = dynamic_cast(sym.symptr.get())) { auto sym_id = symbol->get_id(); GENSYM_INFO("Reading symbol: " + std::to_string(sym_id)); - return sym_env.read(sym); + return EvalRes(sym_env.read(sym), 32); } throw std::runtime_error("Not supported symbolic expression"); } @@ -850,7 +865,8 @@ static void resume_conc_stack(const SymStack_t &sym_stack, Stack_t &stack, stack.resize(sym_stack.size()); for (size_t i = 0; i < sym_stack.size(); ++i) { auto sym = sym_stack[i]; - auto conc = eval_sym_expr(sym, sym_env); + auto res = eval_sym_expr(sym, sym_env); + auto conc = res.value; stack.set_from_front(i, conc); } } @@ -860,7 +876,9 @@ static void resume_conc_frames(const SymFrames_t &sym_frame, Frames_t &frames, frames.resize(sym_frame.size()); for (size_t i = 0; i < sym_frame.size(); ++i) { auto sym = sym_frame[i]; - auto conc = eval_sym_expr(sym, sym_env); + assert(sym.symptr != nullptr); + auto res = eval_sym_expr(sym, sym_env); + auto conc = res.value; frames.set_from_front(i, conc); } } @@ -896,7 +914,9 @@ struct Memory_t { int32_t loadInt(int32_t base, int32_t offset) { // just load a 4-byte integer from memory of the vector int32_t addr = base + offset; - assert(addr + 3 < memory.size()); + if (!(addr + 3 < memory.size())) { + throw std::runtime_error("Invalid memory access" + std::to_string(addr)); + } int32_t result = 0; // Little-endian: lowest byte at lowest address for (int i = 0; i < 4; ++i) { @@ -910,22 +930,28 @@ struct Memory_t { // Load a 4-byte symbolic value from memory SymVal loadSym(int32_t base, int32_t offset) { int32_t addr = base + offset; - assert(addr + 3 < memory.size()); + if (!(addr + 3 < memory.size())) { + throw std::runtime_error("Invalid memory access" + std::to_string(addr)); + } SymVal s0 = memory[addr].second; if (s0.symptr == nullptr) { s0 = SymVal(std::make_shared(8, 0)); + memory[addr].second = s0; } SymVal s1 = memory[addr + 1].second; if (s1.symptr == nullptr) { s1 = SymVal(std::make_shared(8, 0)); + memory[addr + 1].second = s1; } SymVal s2 = memory[addr + 2].second; if (s2.symptr == nullptr) { s2 = SymVal(std::make_shared(8, 0)); + memory[addr + 2].second = s2; } SymVal s3 = memory[addr + 3].second; if (s3.symptr == nullptr) { s3 = SymVal(std::make_shared(8, 0)); + memory[addr + 3].second = s3; } return s3.concat(s2).concat(s1).concat(s0); } diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 03a5df09..ada087cc 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -73,7 +73,7 @@ class TestStagedConcolicEval extends FunSuite { test("mem-sym-extract-concolic") { testFileConcolicCpp("./benchmarks/wasm/mem-sym-extract.wat", None, exitByCoverage=true) } - test("btree-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat") } + test("btree-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat", exitByCoverage = true) } test("return-poly - concrete") { From 827f2b0bf2e4914bc64a6fd73b63b2e4969abf78 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Fri, 3 Oct 2025 13:20:55 -0400 Subject: [PATCH 40/82] preallocate pages for the memory --- headers/wasm/symbolic_rt.hpp | 40 +++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 96b2f039..97568928 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -4,6 +4,7 @@ #include "concrete_rt.hpp" #include "controls.hpp" #include "utils.hpp" +#include "wasm/profile.hpp" #include #include #include @@ -645,6 +646,14 @@ class ExploreTree_t { cursor = root.get(); } + void clear() { + GENSYM_INFO("Clearing the explore tree"); + root = std::make_unique(nullptr); + cursor = root.get(); + true_branch_cov_map.clear(); + false_branch_cov_map.clear(); + } + void set_cursor(NodeBox *new_cursor) { GENSYM_INFO("Setting cursor to a new node"); cursor = new_cursor; @@ -660,6 +669,7 @@ class ExploreTree_t { } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { + Profile.step(ProfileKind::CURSOR_MOVE); assert(cursor != nullptr); auto if_else_node = dynamic_cast(cursor->node.get()); assert( @@ -905,17 +915,30 @@ inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, return cont(mcont); } + +static const int PRE_ALLOC_PAGES = 20; + struct Memory_t { // TODO: We assign a SymVal to each byte in memory std::vector> memory; - - Memory_t(int32_t init_page_count) : memory(init_page_count * pagesize) {} + int page_count; + int allocated_pages; + + Memory_t(int32_t init_page_count) + : memory(PRE_ALLOC_PAGES * pagesize), page_count(init_page_count), + allocated_pages(PRE_ALLOC_PAGES) { + // warm up the memory with zero bytes + for (auto &byte : memory) { + byte.first = 0; + byte.second = SymVal(); + } + } int32_t loadInt(int32_t base, int32_t offset) { // just load a 4-byte integer from memory of the vector int32_t addr = base + offset; if (!(addr + 3 < memory.size())) { - throw std::runtime_error("Invalid memory access" + std::to_string(addr)); + throw std::runtime_error("Invalid memory access " + std::to_string(addr)); } int32_t result = 0; // Little-endian: lowest byte at lowest address @@ -931,7 +954,7 @@ struct Memory_t { SymVal loadSym(int32_t base, int32_t offset) { int32_t addr = base + offset; if (!(addr + 3 < memory.size())) { - throw std::runtime_error("Invalid memory access" + std::to_string(addr)); + throw std::runtime_error("Invalid memory access " + std::to_string(addr)); } SymVal s0 = memory[addr].second; if (s0.symptr == nullptr) { @@ -985,11 +1008,18 @@ struct Memory_t { // grow memory by delta bytes when bytes > 0. return -1 if failed, return old // size when success int32_t grow(int32_t delta) { + Profile.step(ProfileKind::MEM_GROW); if (delta <= 0) { - return memory.size(); + return page_count * pagesize; + } + + if (page_count + delta < allocated_pages) { + page_count += delta; + return page_count * pagesize; } try { + assert(false && "Use pre-allocated memory, should not reach here"); memory.resize(memory.size() + delta * pagesize); auto old_page_count = page_count; page_count += delta; From 75b6347802483974bf643633df56bd72d4e4fbea Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 4 Oct 2025 19:57:15 -0400 Subject: [PATCH 41/82] remove some unperformant code 1. dont intialize memory twice 2. dont allocate memory for unuse symbolic memory, because we need to copy them 3. profiling utilities --- headers/wasm.hpp | 5 +- headers/wasm/concolic_driver.hpp | 28 ++- headers/wasm/concrete_rt.hpp | 126 ++++++++-- headers/wasm/heap_mem_bookkeeper.hpp | 24 ++ headers/wasm/profile.hpp | 114 +++++++++ headers/wasm/symbolic_rt.hpp | 216 +++++++----------- headers/wasm/utils.hpp | 27 ++- .../scala/wasm/StagedConcolicMiniWasm.scala | 6 +- 8 files changed, 386 insertions(+), 160 deletions(-) create mode 100644 headers/wasm/heap_mem_bookkeeper.hpp create mode 100644 headers/wasm/profile.hpp diff --git a/headers/wasm.hpp b/headers/wasm.hpp index 36fe3849..aa93e379 100644 --- a/headers/wasm.hpp +++ b/headers/wasm.hpp @@ -1,8 +1,11 @@ #ifndef WASM_HEADERS #define WASM_HEADERS +#include "wasm/concolic_driver.hpp" #include "wasm/concrete_rt.hpp" +#include "wasm/controls.hpp" +#include "wasm/profile.hpp" #include "wasm/symbolic_rt.hpp" -#include "wasm/concolic_driver.hpp" #include "wasm/utils.hpp" + #endif \ No newline at end of file diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 06b3459c..c9f0b856 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -5,6 +5,9 @@ #include "smt_solver.hpp" #include "symbolic_rt.hpp" #include "utils.hpp" +#include "wasm/profile.hpp" +#include +#include #include #include #include @@ -35,6 +38,7 @@ class ConcolicDriver { void run(); private: + void main_exploration_loop(); Solver solver; std::function entrypoint; std::optional tree_file; @@ -46,13 +50,20 @@ class ManagedConcolicCleanup { public: ManagedConcolicCleanup(const ConcolicDriver &driver) : driver(driver) {} ~ManagedConcolicCleanup() { + // put any cleanup code that needs to be done after each execution here + + // Dump the explore tree if needed if (driver.tree_file.has_value()) ExploreTree.dump_graphviz(driver.tree_file.value()); + + // Clear the symbol bookkeeper + SymBookKeeper.clear(); } }; -inline void ConcolicDriver::run() { - ExploreTree.reset_cursor(); +static std::monostate reset_stacks(); + +inline void ConcolicDriver::main_exploration_loop() { while (true) { ManagedConcolicCleanup cleanup{*this}; @@ -79,6 +90,8 @@ inline void ConcolicDriver::run() { dynamic_cast(unexplored->node.get())) { snapshot_node->get_snapshot().resume_execution(SymEnv, unexplored); } else { + auto timer = ManagedTimer(); + reset_stacks(); entrypoint(); } @@ -97,7 +110,8 @@ inline void ConcolicDriver::run() { GENSYM_INFO("All branches covered, exiting..."); return; } else { - GENSYM_INFO("Found a bug, but not all branches covered, continuing..."); + GENSYM_INFO( + "Found a bug, but not all branches covered, continuing..."); } } } @@ -107,13 +121,19 @@ inline void ConcolicDriver::run() { } } +inline void ConcolicDriver::run() { + ExploreTree.reset_cursor(); + main_exploration_loop(); + Profile.print_summary(); +} + static std::monostate reset_stacks() { Stack.reset(); Frames.reset(); SymStack.reset(); SymFrames.reset(); initRand(); - Memory = Memory_t(1); + Memory.reset(); return std::monostate{}; } diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 5d9243c4..cca614c6 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -1,6 +1,7 @@ #ifndef WASM_CONCRETE_RT_HPP #define WASM_CONCRETE_RT_HPP +#include "wasm/profile.hpp" #include "wasm/utils.hpp" #include #include @@ -8,25 +9,10 @@ #include #include #include +#include #include #include -inline std::monostate info() { -#ifdef DEBUG - std::cout << std::endl; -#endif - return std::monostate{}; -} - -template -std::monostate info(const T &first, const Args &...args) { -#ifdef DEBUG - std::cout << first << " "; - info(args...); -#endif - return std::monostate{}; -} - struct Num { Num(int64_t value) : value(value) {} Num() : value(0) {} @@ -59,24 +45,34 @@ const int STACK_SIZE = 1024 * 64; class Stack_t { public: - Stack_t() : count(0), stack_ptr(new Num[STACK_SIZE]) {} + Stack_t() : count(0), stack_ptr(new Num[STACK_SIZE]) { + size_t page_size = (size_t)sysconf(_SC_PAGESIZE); + // pre touch the memory to avoid page faults during execution + for (int i = 0; i < STACK_SIZE; i += page_size) { + stack_ptr[i] = Num(0); + } + } std::monostate push(Num &&num) { + Profile.step(ProfileKind::PUSH); stack_ptr[count] = num; count++; return std::monostate{}; } std::monostate push(Num &num) { + Profile.step(ProfileKind::PUSH); stack_ptr[count] = num; count++; return std::monostate{}; } Num pop() { + Profile.step(ProfileKind::POP); #ifdef DEBUG assert(count > 0 && "Stack underflow"); - printf("[Debug] poping from stack, size of concrete stack is: %d\n", count); + printf("[Debug] popping from stack, size of concrete stack is: %d\n", + count); #endif Num num = stack_ptr[count - 1]; count--; @@ -84,6 +80,7 @@ class Stack_t { } Num peek() { + Profile.step(ProfileKind::PEEK); #ifdef DEBUG if (count == 0) { throw std::runtime_error("Stack underflow"); @@ -95,6 +92,7 @@ class Stack_t { int32_t size() { return count; } void shift(int32_t offset, int32_t size) { + Profile.step(ProfileKind::SHIFT); #ifdef DEBUG if (offset < 0) { throw std::out_of_range("Invalid offset: " + std::to_string(offset)); @@ -148,7 +146,13 @@ const int FRAME_SIZE = 1024; class Frames_t { public: - Frames_t() : count(0), stack_ptr(new Num[FRAME_SIZE]) {} + Frames_t() : count(0), stack_ptr(new Num[FRAME_SIZE]) { + size_t page_size = (size_t)sysconf(_SC_PAGESIZE); + // pre touch the memory to avoid page faults during execution + for (int i = 0; i < FRAME_SIZE; i += page_size) { + stack_ptr[i] = Num(0); + } + } std::monostate popFrame(std::int32_t size) { assert(size >= 0); @@ -157,11 +161,15 @@ class Frames_t { } Num get(std::int32_t index) { + Profile.step(ProfileKind::GET); auto ret = stack_ptr[count - 1 - index]; return ret; } - void set(std::int32_t index, Num num) { stack_ptr[count - 1 - index] = num; } + void set(std::int32_t index, Num num) { + Profile.step(ProfileKind::SET); + stack_ptr[count - 1 - index] = num; + } void pushFrame(std::int32_t size) { assert(size >= 0); @@ -199,7 +207,85 @@ static std::monostate unreachable() { throw std::runtime_error("Unreachable code reached"); } +static const int PRE_ALLOC_PAGES = 20; static int32_t pagesize = 65536; static int32_t page_count = 0; +struct Memory_t { + // TODO: We assign a SymVal to each byte in memory + std::vector memory; + int init_page_count; + int page_count; + int allocated_pages; + + Memory_t(int32_t init_page_count) + : memory(PRE_ALLOC_PAGES * pagesize), init_page_count(init_page_count), + page_count(init_page_count), allocated_pages(PRE_ALLOC_PAGES) {} + + int32_t loadInt(int32_t base, int32_t offset) { + // just load a 4-byte integer from memory of the vector + int32_t addr = base + offset; + if (!(addr + 3 < memory.size())) { + throw std::runtime_error("Invalid memory access " + std::to_string(addr)); + } + int32_t result = 0; + // Little-endian: lowest byte at lowest address + for (int i = 0; i < 4; ++i) { + result |= static_cast(memory[addr + i]) << (8 * i); + } + return result; + } + + std::monostate storeInt(int32_t base, int32_t offset, int32_t value) { + int32_t addr = base + offset; + // Ensure we don't write out of bounds + assert(addr + 3 < memory.size()); + for (int i = 0; i < 4; ++i) { + memory[addr + i] = static_cast((value >> (8 * i)) & 0xFF); + // Optionally, update memory[addr + i].second (SymVal) if needed + } + return std::monostate{}; + } + + std::monostate store_byte(int32_t addr, uint8_t value) { + assert(addr < memory.size()); + memory[addr] = value; + return std::monostate{}; + } + + // grow memory by delta bytes when bytes > 0. return -1 if failed, return old + // size when success + int32_t grow(int32_t delta) { + Profile.step(ProfileKind::MEM_GROW); + if (delta <= 0) { + return page_count * pagesize; + } + + if (page_count + delta < allocated_pages) { + page_count += delta; + return page_count * pagesize; + } + + try { + assert(false && "Use pre-allocated memory, should not reach here"); + memory.resize(memory.size() + delta * pagesize); + auto old_page_count = page_count; + page_count += delta; + return memory.size(); + } catch (const std::bad_alloc &e) { + return -1; + } + } + + void reset() { + page_count = init_page_count; + allocated_pages = PRE_ALLOC_PAGES; + for (int i = 0; i < memory.size() && i < page_count * pagesize; ++i) { + memory[i] = 0; + } + } +}; + +static Memory_t Memory(1); // 1 page memory + #endif // WASM_CONCRETE_RT_HPP \ No newline at end of file diff --git a/headers/wasm/heap_mem_bookkeeper.hpp b/headers/wasm/heap_mem_bookkeeper.hpp new file mode 100644 index 00000000..c4cc7313 --- /dev/null +++ b/headers/wasm/heap_mem_bookkeeper.hpp @@ -0,0 +1,24 @@ +#ifndef HEAP_MEM_BOOKKEEPER_HPP +#define HEAP_MEM_BOOKKEEPER_HPP + +#include +#include + +// Todo: remove this later, this is just a workaround to make sure that the +// SymVals' memory will not be freed during the main execution. +// We can leave the SymVal's memory unmanaged if reference counting is not +// performant +template struct MemBookKeeper { + std::set> allocated; + + template + std::shared_ptr allocate(Args &&...args) { + auto ptr = std::make_shared(std::forward(args)...); + // allocated.insert(ptr); + return ptr; + } + + void clear() { allocated.clear(); } +}; + +#endif // HEAP_MEM_BOOKKEEPER_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp new file mode 100644 index 00000000..b112c932 --- /dev/null +++ b/headers/wasm/profile.hpp @@ -0,0 +1,114 @@ +#ifndef PROFILE_HPP +#define PROFILE_HPP + +#include "utils.hpp" +#include +#include +#include +#include + +enum class ProfileKind { + PUSH, + POP, + PEEK, + SHIFT, + SET, + GET, + BINARY, + TREE_FILL, + CURSOR_MOVE, + MEM_GROW, + SNAPSHOT_CREATE, + OperationCount // keep this as the last element, this is used to get the + // number of kinds of operations +}; + +class Profile_t { +public: + Profile_t() : step_count(0) {} + std::monostate step() { +#ifdef ENABLE_PROFILE + step_count++; +#endif + return std::monostate(); + } + std::monostate step(ProfileKind op) { +#ifdef ENABLE_PROFILE + op_count[static_cast(op)]++; +#endif + return std::monostate(); + } + void print_summary() { +#ifdef ENABLE_PROFILE + std::cout << "Profile Summary:" << std::endl; + std::cout << "Total PUSH operations: " + << op_count[static_cast(ProfileKind::PUSH)] + << std::endl; + std::cout << "Total POP operations: " + << op_count[static_cast(ProfileKind::POP)] + << std::endl; + std::cout << "Total PEEK operations: " + << op_count[static_cast(ProfileKind::PEEK)] + << std::endl; + std::cout << "Total SHIFT operations: " + << op_count[static_cast(ProfileKind::SHIFT)] + << std::endl; + std::cout << "Total SET operations: " + << op_count[static_cast(ProfileKind::SET)] + << std::endl; + std::cout << "Total GET operations: " + << op_count[static_cast(ProfileKind::GET)] + << std::endl; + std::cout << "Total BINARY operations: " + << op_count[static_cast(ProfileKind::BINARY)] + << std::endl; + std::cout << "Total TREE_FILL operations: " + << op_count[static_cast(ProfileKind::TREE_FILL)] + << std::endl; + std::cout << "Total CURSOR_MOVE operations: " + << op_count[static_cast(ProfileKind::CURSOR_MOVE)] + << std::endl; + std::cout << "Total other instructions executed: " << step_count + << std::endl; + std::cout << "Total MEM_GROW operations: " + << op_count[static_cast(ProfileKind::MEM_GROW)] + << std::endl; + std::cout + << "Total SNAPSHOT_CREATE operations: " + << op_count[static_cast(ProfileKind::SNAPSHOT_CREATE)] + << std::endl; + std::cout << "Total time for instruction execution (s): " + << std::setprecision(15) << execution_time << std::endl; +#endif + } + + // record the time spent in main instruction execution, in seconds + void add_instruction_time(double time) { +#ifdef ENABLE_PROFILE + execution_time += time; +#endif + } + +private: + int step_count; + std::array(ProfileKind::OperationCount)> + op_count; + double execution_time = 0.0; +}; + +static Profile_t Profile; + +class ManagedTimer { +public: + ManagedTimer() { start = std::chrono::high_resolution_clock::now(); } + ~ManagedTimer() { + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = end - start; + Profile.add_instruction_time(elapsed.count()); + } + +private: + std::chrono::high_resolution_clock::time_point start; +}; + +#endif // PROFILE_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 97568928..338afb77 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -3,8 +3,9 @@ #include "concrete_rt.hpp" #include "controls.hpp" +#include "heap_mem_bookkeeper.hpp" +#include "profile.hpp" #include "utils.hpp" -#include "wasm/profile.hpp" #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -60,7 +62,6 @@ class SmallBV : public Symbolic { int size; // in bits int64_t value; }; - struct SymBinary; enum Operation { @@ -77,9 +78,12 @@ enum Operation { B_AND, // Bitwise AND CONCAT, // Byte-level concatenation }; +static MemBookKeeper SymBookKeeper; static std::shared_ptr ZERO = - std::make_shared(I32V(0)); + SymBookKeeper.allocate(I32V(0)); +static std::shared_ptr ZeroByte = + SymBookKeeper.allocate(8, 0); struct SymVal { std::shared_ptr symptr; @@ -115,11 +119,11 @@ struct SymVal { }; static SymVal make_symbolic(int index) { - return SymVal(std::make_shared(index)); + return SymVal(SymBookKeeper.allocate(index)); } inline SymVal Concrete(Num num) { - return SymVal(std::make_shared(num)); + return SymVal(SymBookKeeper.allocate(num)); } // Extract is different from other operations, it only has one symbolic operand, @@ -197,7 +201,7 @@ inline SymVal SymVal::concat(const SymVal &other) const { inline SymVal SymVal::extract(int high, int low) const { assert(high >= low && "Invalid extract range"); - return SymVal(std::make_shared(*this, high, low)); + return SymVal(SymBookKeeper.allocate(*this, high, low)); } inline SymVal SymVal::bitwise_and(const SymVal &other) const { @@ -206,13 +210,13 @@ inline SymVal SymVal::bitwise_and(const SymVal &other) const { inline SymVal SymVal::make_binary(Operation op, const SymVal &lhs, const SymVal &rhs) { assert(lhs.symptr != nullptr && rhs.symptr != nullptr); - return SymVal(std::make_shared(op, lhs, rhs)); + return SymVal(SymBookKeeper.allocate(op, lhs, rhs)); } inline SymVal SymVal::makeSymbolic() const { auto concrete = dynamic_cast(symptr.get()); if (concrete) { // If the symbolic value is a concrete value, use it to create a symbol - return SymVal(std::make_shared(concrete->value.toInt())); + return SymVal(SymBookKeeper.allocate(concrete->value.toInt())); } else { throw std::runtime_error( "Cannot make symbolic a non-concrete symbolic value"); @@ -315,6 +319,55 @@ class SymFrames_t { struct NodeBox; struct SymEnv_t; +class SymMemory_t { +public: + std::unordered_map memory; + + SymVal loadSymByte(int32_t addr) { + // if the address is not in the memory, it must be a zero-initialized memory + auto it = memory.find(addr); + SymVal s = (it != memory.end()) + ? it->second + : SymVal(SymBookKeeper.allocate(8, 0)); + return s; + } + + SymVal loadSym(int32_t base, int32_t offset) { + // calculate the real address + int32_t addr = base + offset; + auto it = memory.find(addr); + SymVal s0 = (it != memory.end()) ? it->second : SymVal(ZeroByte); + it = memory.find(addr + 1); + SymVal s1 = (it != memory.end()) ? it->second : SymVal(ZeroByte); + it = memory.find(addr + 2); + SymVal s2 = (it != memory.end()) ? it->second : SymVal(ZeroByte); + it = memory.find(addr + 3); + SymVal s3 = (it != memory.end()) ? it->second : SymVal(ZeroByte); + + return s3.concat(s2).concat(s1).concat(s0); + } + + // when loading a symval, we need to concat 4 symbolic values + // This sounds terribly bad for SMT... + // Load a 4-byte symbolic value from memory + // Store a 4-byte symbolic value to memory + std::monostate storeSym(int32_t base, int32_t offset, SymVal value) { + int32_t addr = base + offset; + // Extract 4 bytes from that symbol + SymVal s0 = value.extract(1, 1); + SymVal s1 = value.extract(2, 2); + SymVal s2 = value.extract(3, 3); + SymVal s3 = value.extract(4, 4); + memory[addr] = s0; + memory[addr + 1] = s1; + memory[addr + 2] = s2; + memory[addr + 3] = s3; + return std::monostate{}; + } +}; + +static SymMemory_t SymMemory; + // A snapshot of the symbolic state and execution context (control) class Snapshot_t { public: @@ -322,12 +375,14 @@ class Snapshot_t { SymStack_t get_stack() const { return stack; } SymFrames_t get_frames() const { return frames; } + SymMemory_t get_memory() const { return memory; } std::monostate resume_execution(SymEnv_t &sym_env, NodeBox *node) const; private: SymStack_t stack; SymFrames_t frames; + SymMemory_t memory; // The continuation at the snapshot point Cont_t cont; MCont_t mcont; @@ -629,7 +684,9 @@ inline std::vector NodeBox::collect_path_conds() { } inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont) - : stack(SymStack), frames(SymFrames), cont(cont), mcont(mcont) { + : stack(SymStack), frames(SymFrames), memory(SymMemory), cont(cont), + mcont(mcont) { + Profile.step(ProfileKind::SNAPSHOT_CREATE); #ifdef DEBUG std::cout << "Creating snapshot of size " << stack.size() << std::endl; #endif @@ -893,11 +950,28 @@ static void resume_conc_frames(const SymFrames_t &sym_frame, Frames_t &frames, } } +static void resume_conc_memory(const SymMemory_t &sym_memory, Memory_t &memory, + SymEnv_t &sym_env) { + memory.reset(); + for (const auto &pair : sym_memory.memory) { + int32_t addr = pair.first; + SymVal sym = pair.second; + assert(sym.symptr != nullptr); + auto res = eval_sym_expr(sym, sym_env); + auto conc = res.value; + assert(res.width == 8 && "Memory should only store bytes"); + memory.store_byte(addr, conc.value & 0xFF); + } +} + static void resume_conc_states(const SymStack_t &sym_stack, - const SymFrames_t &sym_frame, Stack_t &stack, - Frames_t &frames, SymEnv_t &sym_env) { + const SymFrames_t &sym_frame, + const SymMemory_t &sym_memory, Stack_t &stack, + Frames_t &frames, Memory_t &memory, + SymEnv_t &sym_env) { resume_conc_stack(sym_stack, stack, sym_env); resume_conc_frames(sym_frame, frames, sym_env); + resume_conc_memory(sym_memory, memory, sym_env); } inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, @@ -909,127 +983,11 @@ inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, GENSYM_INFO("Reusing symbolic state from snapshot"); SymStack = stack; SymFrames = frames; + SymMemory = memory; // Restore the concrete states from the symbolic states - resume_conc_states(stack, frames, Stack, Frames, sym_env); + resume_conc_states(stack, frames, memory, Stack, Frames, Memory, sym_env); // Resume execution from the continuation return cont(mcont); } - -static const int PRE_ALLOC_PAGES = 20; - -struct Memory_t { - // TODO: We assign a SymVal to each byte in memory - std::vector> memory; - int page_count; - int allocated_pages; - - Memory_t(int32_t init_page_count) - : memory(PRE_ALLOC_PAGES * pagesize), page_count(init_page_count), - allocated_pages(PRE_ALLOC_PAGES) { - // warm up the memory with zero bytes - for (auto &byte : memory) { - byte.first = 0; - byte.second = SymVal(); - } - } - - int32_t loadInt(int32_t base, int32_t offset) { - // just load a 4-byte integer from memory of the vector - int32_t addr = base + offset; - if (!(addr + 3 < memory.size())) { - throw std::runtime_error("Invalid memory access " + std::to_string(addr)); - } - int32_t result = 0; - // Little-endian: lowest byte at lowest address - for (int i = 0; i < 4; ++i) { - result |= static_cast(memory[addr + i].first) << (8 * i); - } - return result; - } - - // TODO: when loading a symval, we need to concat 4 symbolic values - // This sounds terribly bad for SMT... - // Load a 4-byte symbolic value from memory - SymVal loadSym(int32_t base, int32_t offset) { - int32_t addr = base + offset; - if (!(addr + 3 < memory.size())) { - throw std::runtime_error("Invalid memory access " + std::to_string(addr)); - } - SymVal s0 = memory[addr].second; - if (s0.symptr == nullptr) { - s0 = SymVal(std::make_shared(8, 0)); - memory[addr].second = s0; - } - SymVal s1 = memory[addr + 1].second; - if (s1.symptr == nullptr) { - s1 = SymVal(std::make_shared(8, 0)); - memory[addr + 1].second = s1; - } - SymVal s2 = memory[addr + 2].second; - if (s2.symptr == nullptr) { - s2 = SymVal(std::make_shared(8, 0)); - memory[addr + 2].second = s2; - } - SymVal s3 = memory[addr + 3].second; - if (s3.symptr == nullptr) { - s3 = SymVal(std::make_shared(8, 0)); - memory[addr + 3].second = s3; - } - return s3.concat(s2).concat(s1).concat(s0); - } - - // Store a 4-byte symbolic value to memory - std::monostate storeSym(int32_t base, int32_t offset, SymVal value) { - int32_t addr = base + offset; - // Extract 4 bytes from that symbol - SymVal s0 = value.extract(1, 1); - SymVal s1 = value.extract(2, 2); - SymVal s2 = value.extract(3, 3); - SymVal s3 = value.extract(4, 4); - memory[addr].second = s0; - memory[addr + 1].second = s1; - memory[addr + 2].second = s2; - memory[addr + 3].second = s3; - return std::monostate{}; - } - - std::monostate storeInt(int32_t base, int32_t offset, int32_t value) { - int32_t addr = base + offset; - // Ensure we don't write out of bounds - assert(addr + 3 < memory.size()); - for (int i = 0; i < 4; ++i) { - memory[addr + i].first = static_cast((value >> (8 * i)) & 0xFF); - // Optionally, update memory[addr + i].second (SymVal) if needed - } - return std::monostate{}; - } - - // grow memory by delta bytes when bytes > 0. return -1 if failed, return old - // size when success - int32_t grow(int32_t delta) { - Profile.step(ProfileKind::MEM_GROW); - if (delta <= 0) { - return page_count * pagesize; - } - - if (page_count + delta < allocated_pages) { - page_count += delta; - return page_count * pagesize; - } - - try { - assert(false && "Use pre-allocated memory, should not reach here"); - memory.resize(memory.size() + delta * pagesize); - auto old_page_count = page_count; - page_count += delta; - return memory.size(); - } catch (const std::bad_alloc &e) { - return -1; - } - } -}; - -static Memory_t Memory(1); // 1 page memory - #endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file diff --git a/headers/wasm/utils.hpp b/headers/wasm/utils.hpp index f814858d..8b7b0471 100644 --- a/headers/wasm/utils.hpp +++ b/headers/wasm/utils.hpp @@ -1,5 +1,7 @@ #ifndef UTILS_HPP #define UTILS_HPP +#include +#include #ifndef GENSYM_ASSERT #define GENSYM_ASSERT(condition) \ @@ -39,15 +41,34 @@ #if __cplusplus < 202002L #include -inline bool starts_with(const std::string& str, const std::string& prefix) { +inline bool starts_with(const std::string &str, const std::string &prefix) { return str.size() >= prefix.size() && - std::equal(prefix.begin(), prefix.end(), str.begin()); + std::equal(prefix.begin(), prefix.end(), str.begin()); } #else #include -inline bool starts_with(const std::string& str, const std::string& prefix) { +inline bool starts_with(const std::string &str, const std::string &prefix) { return str.starts_with(prefix); } #endif +inline std::monostate info() { +#ifdef DEBUG + std::cout << std::endl; +#endif + return std::monostate{}; +} + +template +std::monostate info(const T &first, const Args &...args) { +#ifdef DEBUG + std::cout << first << " "; + info(args...); +#endif + return std::monostate{}; +} + +inline std::monostate get_unit() { return std::monostate{}; } +inline std::monostate get_unit(std::monostate x) { return std::monostate{}; } + #endif // UTILS_HPP \ No newline at end of file diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 5b5ae8de..86d86a8a 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -626,7 +626,7 @@ trait StagedWasmEvaluator extends SAIOps { } } val (instrs, locals) = (funBody.body, funBody.locals) - resetStacks() + // resetStacks() // Don't manually reset the global states (like stack), manage them in the driver initGlobals(module.globals) Frames.pushFrameC(locals) Frames.pushFrameS(locals) @@ -1409,9 +1409,9 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.size()") // Symbolic Memory case Node(_, "sym-store-int", List(base, offset, s_value), _) => - emit("Memory.storeSym("); shallow(base); emit(", "); shallow(offset); emit(", "); shallow(s_value); emit(")") + emit("SymMemory.storeSym("); shallow(base); emit(", "); shallow(offset); emit(", "); shallow(s_value); emit(")") case Node(_, "sym-load-int", List(base, offset), _) => - emit("Memory.loadSym("); shallow(base); emit(", "); shallow(offset); emit(")") + emit("SymMemory.loadSym("); shallow(base); emit(", "); shallow(offset); emit(")") case Node(_, "sym-memory-grow", List(delta), _) => emit("SymMemory.grow("); shallow(delta); emit(")") // Globals From 8a40d30b4a5d3c6b92b7ed712deba4567d74baea Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 4 Oct 2025 21:51:43 -0400 Subject: [PATCH 42/82] work list algorithm for exploration --- headers/wasm/concolic_driver.hpp | 39 ++++++++++++++++++++++++-------- headers/wasm/symbolic_rt.hpp | 36 +++++++++++++++++------------ 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index c9f0b856..e49a99e8 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -42,6 +42,7 @@ class ConcolicDriver { Solver solver; std::function entrypoint; std::optional tree_file; + std::vector work_list; }; class ManagedConcolicCleanup { @@ -64,19 +65,39 @@ class ManagedConcolicCleanup { static std::monostate reset_stacks(); inline void ConcolicDriver::main_exploration_loop() { - while (true) { + + // Register a collector to ExploreTree to add new nodes to work_list + ExploreTree.register_new_node_collector( + [&](NodeBox *new_node) { work_list.push_back(new_node); }); + + std::set visited; + + assert(ExploreTree.get_root()->isUnexplored() && + "Before main loop, root should be unexplored!"); + work_list.push_back(ExploreTree.get_root()); + + while (!work_list.empty()) { ManagedConcolicCleanup cleanup{*this}; + // Pick an unexplored node from the work list + auto node = work_list.back(); + work_list.pop_back(); - auto unexplored = ExploreTree.pick_unexplored(); - if (!unexplored) { - GENSYM_INFO("No unexplored nodes found, exiting..."); - return; + if (visited.find(node) != visited.end()) { + continue; + } else { + visited.insert(node); } - auto cond = unexplored->collect_path_conds(); + + if (!node->isUnexplored()) { + // if it's not unexplored anymore, skip it + continue; + } + + auto cond = node->collect_path_conds(); auto result = solver.solve(cond); if (!result.has_value()) { GENSYM_INFO("Found an unreachable path, marking it as unreachable..."); - unexplored->fillUnreachableNode(); + node->fillUnreachableNode(); continue; } auto new_env = result.value(); @@ -87,8 +108,8 @@ inline void ConcolicDriver::main_exploration_loop() { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); if (auto snapshot_node = - dynamic_cast(unexplored->node.get())) { - snapshot_node->get_snapshot().resume_execution(SymEnv, unexplored); + dynamic_cast(node->node.get())) { + snapshot_node->get_snapshot().resume_execution(SymEnv, node); } else { auto timer = ManagedTimer(); reset_stacks(); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 338afb77..1cc3fb2d 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -420,7 +420,7 @@ struct NodeBox { std::unique_ptr node; NodeBox *parent; - std::monostate fillIfElseNode(SymVal cond, int id); + bool fillIfElseNode(SymVal cond, int id); std::monostate fillFinishedNode(); std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); @@ -610,15 +610,16 @@ inline NodeBox::NodeBox(NodeBox *parent) /* TODO: avoid allocation of unexplored node */ parent(parent) {} -inline std::monostate NodeBox::fillIfElseNode(SymVal cond, int id) { +inline bool NodeBox::fillIfElseNode(SymVal cond, int id) { // fill the current NodeBox with an ifelse branch node when it's unexplored if (this->isUnexplored()) { node = std::make_unique(cond, this, id); + return true; } assert( dynamic_cast(node.get()) != nullptr && "Current node is not an Unexplored nor an IfElseNode, cannot fill it!"); - return std::monostate(); + return false; } inline std::monostate NodeBox::fillSnapshotNode(Snapshot_t snapshot) { @@ -722,7 +723,12 @@ class ExploreTree_t { std::monostate fillFailedNode() { return cursor->fillFailedNode(); } std::monostate fillIfElseNode(SymVal cond, int id) { - return cursor->fillIfElseNode(cond, id); + if (cursor->fillIfElseNode(cond, id)) { + auto if_else_node = dynamic_cast(cursor->node.get()); + register_new_node(if_else_node->true_branch.get()); + register_new_node(if_else_node->false_branch.get()); + } + return std::monostate(); } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { @@ -764,16 +770,6 @@ class ExploreTree_t { return std::monostate(); } - std::optional> get_unexplored_conditions() { - // Get all unexplored conditions in the tree - std::vector result; - auto box = pick_unexplored(); - if (!box) { - return std::nullopt; - } - return box->collect_path_conds(); - } - NodeBox *pick_unexplored() { // Pick an unexplored node from the tree // For now, we just iterate through the tree and return the first unexplored @@ -793,6 +789,12 @@ class ExploreTree_t { return true; } + NodeBox *get_root() const { return root.get(); } + + void register_new_node_collector(std::function func) { + new_node_collectors.push_back(func); + } + private: NodeBox *pick_unexplored_of(NodeBox *node) { if (node->isUnexplored()) { @@ -808,8 +810,14 @@ class ExploreTree_t { } return nullptr; // No unexplored node found } + void register_new_node(NodeBox *node) { + for (auto &func : new_node_collectors) { + func(node); + } + } std::unique_ptr root; NodeBox *cursor; + std::vector> new_node_collectors; }; static ExploreTree_t ExploreTree; From 568928c53494ac69fa6e92836f086e8d7df4c9c8 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 5 Oct 2025 12:20:09 -0400 Subject: [PATCH 43/82] config header; fix extract evaluation; capture by value in lambda --- headers/wasm/concolic_driver.hpp | 26 ++---- headers/wasm/concrete_rt.hpp | 47 +++++++--- headers/wasm/config.hpp | 36 +++++++ headers/wasm/profile.hpp | 93 +++++++++---------- headers/wasm/symbolic_rt.hpp | 72 +++++++------- .../scala/wasm/StagedConcolicMiniWasm.scala | 15 +-- 6 files changed, 166 insertions(+), 123 deletions(-) create mode 100644 headers/wasm/config.hpp diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index e49a99e8..37ef4004 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -2,10 +2,11 @@ #define CONCOLIC_DRIVER_HPP #include "concrete_rt.hpp" +#include "config.hpp" +#include "profile.hpp" #include "smt_solver.hpp" #include "symbolic_rt.hpp" #include "utils.hpp" -#include "wasm/profile.hpp" #include #include #include @@ -15,16 +16,6 @@ #include #include -enum class ExploreMode { EarlyExit, ExitByCoverage }; - -#ifdef EARLY_EXIT -static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; -#elif defined(BY_COVERAGE) -static const ExploreMode EXPLORE_MODE = ExploreMode::ExitByCoverage; -#else -static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; -#endif - class ConcolicDriver { friend class ManagedConcolicCleanup; @@ -107,12 +98,14 @@ inline void ConcolicDriver::main_exploration_loop() { try { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); - if (auto snapshot_node = - dynamic_cast(node->node.get())) { + if (auto snapshot_node = dynamic_cast(node->node.get())) { + assert(REUSE_SNAPSHOT); + auto timer = ManagedTimer(); snapshot_node->get_snapshot().resume_execution(SymEnv, node); } else { auto timer = ManagedTimer(); reset_stacks(); + ExploreTree.reset_cursor(); entrypoint(); } @@ -134,6 +127,7 @@ inline void ConcolicDriver::main_exploration_loop() { GENSYM_INFO( "Found a bug, but not all branches covered, continuing..."); } + std::cout << e.what() << std::endl; } } #if defined(RUN_ONCE) @@ -143,18 +137,18 @@ inline void ConcolicDriver::main_exploration_loop() { } inline void ConcolicDriver::run() { - ExploreTree.reset_cursor(); main_exploration_loop(); Profile.print_summary(); } static std::monostate reset_stacks() { Stack.reset(); - Frames.reset(); SymStack.reset(); + Frames.reset(); SymFrames.reset(); - initRand(); Memory.reset(); + SymMemory.reset(); + initRand(); return std::monostate{}; } diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index cca614c6..c75c0215 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -17,24 +17,30 @@ struct Num { Num(int64_t value) : value(value) {} Num() : value(0) {} int64_t value; - int32_t toInt() { return static_cast(value); } + int32_t toInt() const { return static_cast(value); } - bool operator==(const Num &other) const { return value == other.value; } + // TODO: support different bit width operations, for now we just assume all + // oprands are i32 + bool operator==(const Num &other) const { return toInt() == other.toInt(); } bool operator!=(const Num &other) const { return !(*this == other); } - Num operator+(const Num &other) const { return Num(value + other.value); } - Num operator-(const Num &other) const { return Num(value - other.value); } - Num operator*(const Num &other) const { return Num(value * other.value); } + Num operator+(const Num &other) const { return Num(toInt() + other.toInt()); } + Num operator-(const Num &other) const { return Num(toInt() - other.toInt()); } + Num operator*(const Num &other) const { return Num(toInt() * other.toInt()); } Num operator/(const Num &other) const { - if (other.value == 0) { + if (other.toInt() == 0) { throw std::runtime_error("Division by zero"); } - return Num(value / other.value); + return Num(toInt() / other.toInt()); } - Num operator<(const Num &other) const { return Num(value < other.value); } - Num operator<=(const Num &other) const { return Num(value <= other.value); } - Num operator>(const Num &other) const { return Num(value > other.value); } - Num operator>=(const Num &other) const { return Num(value >= other.value); } - Num operator&(const Num &other) const { return Num(value & other.value); } + Num operator<(const Num &other) const { return Num(toInt() < other.toInt()); } + Num operator<=(const Num &other) const { + return Num(toInt() <= other.toInt()); + } + Num operator>(const Num &other) const { return Num(toInt() > other.toInt()); } + Num operator>=(const Num &other) const { + return Num(toInt() >= other.toInt()); + } + Num operator&(const Num &other) const { return Num(toInt() & other.toInt()); } }; static Num I32V(int v) { return v; } @@ -71,8 +77,9 @@ class Stack_t { Profile.step(ProfileKind::POP); #ifdef DEBUG assert(count > 0 && "Stack underflow"); - printf("[Debug] popping from stack, size of concrete stack is: %d\n", - count); + printf("[Debug] popping a value %ld from stack, size of concrete stack is: " + "%d\n", + stack_ptr[count - 1].value, count); #endif Num num = stack_ptr[count - 1]; count--; @@ -223,6 +230,10 @@ struct Memory_t { page_count(init_page_count), allocated_pages(PRE_ALLOC_PAGES) {} int32_t loadInt(int32_t base, int32_t offset) { +#ifdef DEBUG + std::cout << "[Debug] loading int from memory at address: " + << (base + offset) << std::endl; +#endif // just load a 4-byte integer from memory of the vector int32_t addr = base + offset; if (!(addr + 3 < memory.size())) { @@ -238,8 +249,14 @@ struct Memory_t { std::monostate storeInt(int32_t base, int32_t offset, int32_t value) { int32_t addr = base + offset; +#ifdef DEBUG + std::cout << "[Debug] storing int " << value << " to memory at address " + << addr << std::endl; +#endif // Ensure we don't write out of bounds - assert(addr + 3 < memory.size()); + if (!(addr + 3 < memory.size())) { + throw std::runtime_error("Invalid memory access " + std::to_string(addr)); + } for (int i = 0; i < 4; ++i) { memory[addr + i] = static_cast((value >> (8 * i)) & 0xFF); // Optionally, update memory[addr + i].second (SymVal) if needed diff --git a/headers/wasm/config.hpp b/headers/wasm/config.hpp new file mode 100644 index 00000000..48a54634 --- /dev/null +++ b/headers/wasm/config.hpp @@ -0,0 +1,36 @@ +#ifndef CONFIG_HPP +#define CONFIG_HPP + +// This file contains configuration settings for the concolic execution + +// If ENABLE_PROFILE defined, the compiled program will collect and print +// profiling information +#ifdef ENABLE_PROFILE +const bool PROFILE_ENABLED = true; +#else +const bool PROFILE_ENABLED = false; +#endif + +// This variable define when concolic execution will stop +enum class ExploreMode { + EarlyExit, // Stop at the first error encountered + + ExitByCoverage // Exit when all syntactic branches are covered +}; + +#ifdef EARLY_EXIT +static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; +#elif defined(BY_COVERAGE) +static const ExploreMode EXPLORE_MODE = ExploreMode::ExitByCoverage; +#else +static const ExploreMode EXPLORE_MODE = ExploreMode::EarlyExit; +#endif + +// This variable decides whether we enable the snapshot reuse optimization +#ifdef NO_REUSE +static const bool REUSE_SNAPSHOT = false; +#else +static const bool REUSE_SNAPSHOT = true; +#endif + +#endif // CONFIG_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index b112c932..ec17448a 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -2,6 +2,7 @@ #define PROFILE_HPP #include "utils.hpp" +#include "config.hpp" #include #include #include @@ -27,59 +28,57 @@ class Profile_t { public: Profile_t() : step_count(0) {} std::monostate step() { -#ifdef ENABLE_PROFILE - step_count++; -#endif + if (PROFILE_ENABLED) + step_count++; return std::monostate(); } std::monostate step(ProfileKind op) { -#ifdef ENABLE_PROFILE - op_count[static_cast(op)]++; -#endif + if (PROFILE_ENABLED) + op_count[static_cast(op)]++; return std::monostate(); } void print_summary() { -#ifdef ENABLE_PROFILE - std::cout << "Profile Summary:" << std::endl; - std::cout << "Total PUSH operations: " - << op_count[static_cast(ProfileKind::PUSH)] - << std::endl; - std::cout << "Total POP operations: " - << op_count[static_cast(ProfileKind::POP)] - << std::endl; - std::cout << "Total PEEK operations: " - << op_count[static_cast(ProfileKind::PEEK)] - << std::endl; - std::cout << "Total SHIFT operations: " - << op_count[static_cast(ProfileKind::SHIFT)] - << std::endl; - std::cout << "Total SET operations: " - << op_count[static_cast(ProfileKind::SET)] - << std::endl; - std::cout << "Total GET operations: " - << op_count[static_cast(ProfileKind::GET)] - << std::endl; - std::cout << "Total BINARY operations: " - << op_count[static_cast(ProfileKind::BINARY)] - << std::endl; - std::cout << "Total TREE_FILL operations: " - << op_count[static_cast(ProfileKind::TREE_FILL)] - << std::endl; - std::cout << "Total CURSOR_MOVE operations: " - << op_count[static_cast(ProfileKind::CURSOR_MOVE)] - << std::endl; - std::cout << "Total other instructions executed: " << step_count - << std::endl; - std::cout << "Total MEM_GROW operations: " - << op_count[static_cast(ProfileKind::MEM_GROW)] - << std::endl; - std::cout - << "Total SNAPSHOT_CREATE operations: " - << op_count[static_cast(ProfileKind::SNAPSHOT_CREATE)] - << std::endl; - std::cout << "Total time for instruction execution (s): " - << std::setprecision(15) << execution_time << std::endl; -#endif + if (PROFILE_ENABLED) { + std::cout << "Profile Summary:" << std::endl; + std::cout << "Total PUSH operations: " + << op_count[static_cast(ProfileKind::PUSH)] + << std::endl; + std::cout << "Total POP operations: " + << op_count[static_cast(ProfileKind::POP)] + << std::endl; + std::cout << "Total PEEK operations: " + << op_count[static_cast(ProfileKind::PEEK)] + << std::endl; + std::cout << "Total SHIFT operations: " + << op_count[static_cast(ProfileKind::SHIFT)] + << std::endl; + std::cout << "Total SET operations: " + << op_count[static_cast(ProfileKind::SET)] + << std::endl; + std::cout << "Total GET operations: " + << op_count[static_cast(ProfileKind::GET)] + << std::endl; + std::cout << "Total BINARY operations: " + << op_count[static_cast(ProfileKind::BINARY)] + << std::endl; + std::cout << "Total TREE_FILL operations: " + << op_count[static_cast(ProfileKind::TREE_FILL)] + << std::endl; + std::cout << "Total CURSOR_MOVE operations: " + << op_count[static_cast(ProfileKind::CURSOR_MOVE)] + << std::endl; + std::cout << "Total other instructions executed: " << step_count + << std::endl; + std::cout << "Total MEM_GROW operations: " + << op_count[static_cast(ProfileKind::MEM_GROW)] + << std::endl; + std::cout + << "Total SNAPSHOT_CREATE operations: " + << op_count[static_cast(ProfileKind::SNAPSHOT_CREATE)] + << std::endl; + std::cout << "Total time for instruction execution (s): " + << std::setprecision(15) << execution_time << std::endl; + } } // record the time spent in main instruction execution, in seconds diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 1cc3fb2d..cc7c2d7b 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -2,6 +2,7 @@ #define WASM_SYMBOLIC_RT_HPP #include "concrete_rt.hpp" +#include "config.hpp" #include "controls.hpp" #include "heap_mem_bookkeeper.hpp" #include "profile.hpp" @@ -29,12 +30,6 @@ class Symbolic { static int max_id = 0; -#ifdef NO_REUSE -static bool REUSE_MODE = false; -#else -static bool REUSE_MODE = true; -#endif - class Symbol : public Symbolic { public: // TODO: add type information to determine the size of bitvector @@ -265,8 +260,6 @@ class SymStack_t { stack.clear(); } - void reuse(Snapshot_t snapshot); - size_t size() const { return stack.size(); } SymVal operator[](size_t index) const { return stack[index]; } @@ -306,8 +299,6 @@ class SymFrames_t { stack.clear(); } - void reuse(Snapshot_t snapshot); - size_t size() const { return stack.size(); } SymVal operator[](size_t index) const { return stack[index]; } @@ -364,6 +355,11 @@ class SymMemory_t { memory[addr + 3] = s3; return std::monostate{}; } + + std::monostate reset() { + memory.clear(); + return std::monostate{}; + } }; static SymMemory_t SymMemory; @@ -371,7 +367,9 @@ static SymMemory_t SymMemory; // A snapshot of the symbolic state and execution context (control) class Snapshot_t { public: - explicit Snapshot_t(Cont_t cont, MCont_t mcont); + explicit Snapshot_t(Cont_t cont, MCont_t mcont, SymStack_t stack, + SymFrames_t frames, SymMemory_t memory); + explicit Snapshot_t() {} SymStack_t get_stack() const { return stack; } SymFrames_t get_frames() const { return frames; } @@ -388,31 +386,18 @@ class Snapshot_t { MCont_t mcont; }; -inline void SymStack_t::reuse(Snapshot_t snapshot) { -// Reusing the symbolic stack from the snapshot -#ifdef DEBUG - std::cout << "Reusing symbolic state from snapshot" << std::endl; - std::cout << "Old stack size = " << stack.size() << std::endl; - std::cout << "New stack size = " << snapshot.get_stack().stack.size() - << std::endl; -#endif - stack = snapshot.get_stack().stack; -} - -inline void SymFrames_t::reuse(Snapshot_t snapshot) { -// Reusing the symbolic frames from the snapshot -#ifdef DEBUG - std::cout << "Reusing symbolic state from snapshot" << std::endl; - std::cout << "Old frame size = " << stack.size() << std::endl; - std::cout << "New frame size = " << snapshot.get_frames().stack.size() - << std::endl; -#endif - stack = snapshot.get_frames().stack; -} - static SymFrames_t SymFrames; static SymFrames_t SymGlobals; +static Snapshot_t makeSnapshot(Cont_t cont, MCont_t mcont) { + if (REUSE_SNAPSHOT) { + return Snapshot_t(cont, mcont, SymStack, SymFrames, SymMemory); + } else { + // create a dummy snapshot, which will not be used + return Snapshot_t(); + } +} + struct Node; struct NodeBox { @@ -684,9 +669,10 @@ inline std::vector NodeBox::collect_path_conds() { return result; } -inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont) - : stack(SymStack), frames(SymFrames), memory(SymMemory), cont(cont), - mcont(mcont) { +inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont, SymStack_t stack, + SymFrames_t frames, SymMemory_t memory) + : stack(std::move(stack)), frames(std::move(frames)), + memory(std::move(memory)), cont(cont), mcont(mcont) { Profile.step(ProfileKind::SNAPSHOT_CREATE); #ifdef DEBUG std::cout << "Creating snapshot of size " << stack.size() << std::endl; @@ -740,11 +726,19 @@ class ExploreTree_t { "Can't move cursor when the branch node is not initialized correctly!"); if (branch) { true_branch_cov_map[if_else_node->id] = true; - if_else_node->false_branch->fillSnapshotNode(snapshot); + if (REUSE_SNAPSHOT) { + if_else_node->false_branch->fillSnapshotNode(snapshot); + } else { + // Do nothing, the initial value of the branch is an unexplored node + } cursor = if_else_node->true_branch.get(); } else { false_branch_cov_map[if_else_node->id] = true; - if_else_node->true_branch->fillSnapshotNode(snapshot); + if (REUSE_SNAPSHOT) { + if_else_node->true_branch->fillSnapshotNode(snapshot); + } else { + // Do nothing, the initial value of the branch is an unexplored node + } cursor = if_else_node->false_branch.get(); } @@ -884,7 +878,7 @@ static EvalRes eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { assert(high >= low && "Invalid extract range"); int size = high - low + 1; // size in bytes int64_t mask = (1LL << (size * 8)) - 1; - int64_t extracted_value = (res.value.toInt() >> (low * 8)) & mask; + int64_t extracted_value = (res.value.toInt() >> ((low - 1) * 8)) & mask; return EvalRes(Num(I64V(extracted_value)), size * 8); } else if (auto smallbv = dynamic_cast(sym.symptr.get())) { return EvalRes(Num(I64V(smallbv->get_value())), smallbv->get_size()); diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 86d86a8a..c07ecbbc 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -344,11 +344,11 @@ trait StagedWasmEvaluator extends SAIOps { val id = Counter.getId(inst) ExploreTree.fillWithIfElse(symCond.s, id) def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { - info("Entering the true branch of the if") + info(s"Entering the true branch $id of the if") eval(thn, restK _, mk, restK _ :: trail)(newCtx) }) def elsK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { - info("Entering the false branch of the if") + info(s"Entering the false branch $id of the if") eval(els, restK _, mk, restK _ :: trail)(newCtx) }) if (cond.toInt != 0) { @@ -407,13 +407,13 @@ trait StagedWasmEvaluator extends SAIOps { // snapshotNode (this is done by moveCursor's runtime implementation) // TODO: store snapshot into this snapshot node def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { - info("Entering the true branch of the br_table") + info(s"Entering the true branch $id of the br_table") Stack.popC(ty) Stack.popS(ty) trail(choices.head)(newCtx)(mk) }) def elsK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { - info("Entering the false branch of the br_table") + info(s"Entering the false branch $id of the br_table") aux(choices.tail, idx + 1, mk) }) if (cond.toInt != 0) { @@ -1361,7 +1361,10 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { val argTypes = b.in.map(a => remap(typeMap(a))).mkString(", ") emitln(s"std::function<$retType(${argTypes})> ${quote(f)};") emit(quote(f)); emit(" = ") - quoteTypedBlock(b, false, true, capture = "&") + // We need to capture by value here, because we want to save a function in + // snapshot, and use the function later, while the local variables have + // been released. + quoteTypedBlock(b, false, true, capture = "=") emitln(";") case _ => super.traverse(n) } @@ -1386,7 +1389,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "sym-stack-pop", _, _) => emit("SymStack.pop()") case Node(_, "snapshot-make", List(k, mk), _) => - emit("Snapshot_t("); shallow(k); emit(", "); shallow(mk); emit(")") + emit("makeSnapshot("); shallow(k); emit(", "); shallow(mk); emit(")") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(")") case Node(_, "sym-frame-pop", List(i), _) => From ee9e57bedf0c7b43163c58bd13d2edd972bae6d0 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 5 Oct 2025 19:33:14 -0400 Subject: [PATCH 44/82] replace SymEnv_t's underlying representation --- headers/wasm/smt_solver.hpp | 7 ++----- headers/wasm/symbolic_rt.hpp | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 64952bcc..8625a65d 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -14,7 +14,7 @@ class Solver { public: Solver() {} - std::optional> solve(const std::vector &conditions) { + std::optional solve(const std::vector &conditions) { // make an conjunction of all conditions z3::expr conjunction = z3_ctx.bool_val(true); for (const auto &cond : conditions) { @@ -33,7 +33,7 @@ class Solver { return std::nullopt; // No solution found case z3::sat: { z3::model model = z3_solver.get_model(); - std::vector result; + NumMap result; // Reference: // https://github.com/Z3Prover/z3/blob/master/examples/c%2B%2B/example.cpp#L59 GENSYM_INFO("Solved Z3 model"); @@ -44,9 +44,6 @@ class Solver { std::string name = var.name().str(); if (starts_with(name, "s_")) { int id = std::stoi(name.substr(2)); - if (id >= result.size()) { - result.resize(id + 1); - } result[id] = Num(value.get_numeral_int64()); } else { GENSYM_INFO("Find a variable that is not created by GenSym: " + name); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index cc7c2d7b..8ecd207d 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -816,36 +816,36 @@ class ExploreTree_t { static ExploreTree_t ExploreTree; +using NumMap = std::unordered_map; + class SymEnv_t { public: Num read(const Symbol &symbol) { - if (symbol.get_id() >= map.size()) { - map.resize(symbol.get_id() + 1); - } #if DEBUG std::cout << "Read symbol: " << symbol.get_id() << " from symbolic environment" << std::endl; std::cout << "Current symbolic environment: " << to_string() << std::endl; #endif - - return map[symbol.get_id()]; + map.try_emplace(symbol.get_id(), Num(I32V(0))); + return map.at(symbol.get_id()); } Num read(SymVal sym) { + // Read the value of a symbolic value from the environment, it will update + // the environment if the key does not exist. auto symbol = dynamic_cast(sym.symptr.get()); assert(symbol); return read(*symbol); } - void update(std::vector new_env) { map = std::move(new_env); } + void update(NumMap new_env) { map = std::move(new_env); } std::string to_string() const { std::string result; result += "(\n"; - for (int i = 0; i < map.size(); ++i) { - const Num &num = map[i]; + for (const auto &[id, num] : map) { result += - " (" + std::to_string(i) + "->" + std::to_string(num.value) + ")\n"; + " (" + std::to_string(id) + "->" + std::to_string(num.value) + ")\n"; } result += ")"; return result; @@ -854,7 +854,7 @@ class SymEnv_t { size_t size() const { return map.size(); } private: - std::vector map; // The symbolic environment, a vector of Num + NumMap map; // The symbolic environment, a vector of Num }; static SymEnv_t SymEnv; From bd5036bcf41eee87dbef13e9f21bef9dd683e793 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 5 Oct 2025 19:53:13 -0400 Subject: [PATCH 45/82] compare the exploration trees (w/ vs. w/o snapshot reuse) --- .../genwasym/TestStagedConcolicEval.scala | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index ada087cc..a0877796 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -12,15 +12,38 @@ class TestStagedConcolicEval extends FunSuite { def testFileConcolicCpp(filename: String, main: Option[String] = None, exitByCoverage: Boolean = false) = { + import sys.process._ + + val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" - val exe = s"$cppFile.exe" - val exploreTreeFile = s"$filename.tree.dot" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") - - import sys.process._ - val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! - println(result) + val exploreTreeFile = { + // Do concolic execution with snapshot reuse + val exe = s"$cppFile.exe" + val exploreTreeFile = s"$filename.tree.dot" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") + println(s"Running compiled concolic execution with snapshot reuse: $exe") + val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! + println(result) + exploreTreeFile + } + val exploreTreeFileNoReuse = { + // Do concolic execution without snapshot reuse + val exe = s"$cppFile.noreuse.exe" + val exploreTreeFile = s"$filename.noreuse.tree.dot" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, false, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") + println(s"Running compiled concolic execution without snapshot reuse: $exe") + val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! + println(result) + exploreTreeFile + } + // The explore tree generated by two executions should be same + import java.nio.file.Files + assert( + Files.readAllBytes(java.nio.file.Paths.get(exploreTreeFile)) + sameElements Files.readAllBytes(java.nio.file.Paths.get(exploreTreeFileNoReuse)), + s"Explore trees $exploreTreeFile and $exploreTreeFileNoReuse are different!" + ) } // only test concrete execution and its result From f63f682ec919535a9fa91b386ec3dda7a09acc4d Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 5 Oct 2025 20:01:48 -0400 Subject: [PATCH 46/82] accelerate test by using O0 optimization --- src/main/scala/wasm/StagedConcolicMiniWasm.scala | 3 ++- src/test/scala/genwasym/TestStagedConcolicEval.scala | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index c07ecbbc..739a0f39 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -1590,6 +1590,7 @@ object WasmToCppCompiler { outputCpp: String, outputExe: String, printRes: Boolean, + optimizeLevel: Int, macros: String*): Unit = { val generated = compile(moduleInst, main, printRes) val code = generated.source @@ -1604,7 +1605,7 @@ object WasmToCppCompiler { import sys.process._ val includeFlags = generated.headerFolders.map(f => s"-I$f").mkString(" ") val macroFlags = macros.map(m => s"-D$m").mkString(" ") - val command = s"g++ -std=c++17 $outputCpp -o $outputExe -O3 -g -l z3 " + includeFlags + " " + macroFlags + val command = s"g++ -std=c++17 $outputCpp -o $outputExe -O$optimizeLevel -g -l z3 " + includeFlags + " " + macroFlags if (command.! != 0) { throw new RuntimeException(s"Compilation failed for $outputCpp") } diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index a0877796..68009388 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -21,7 +21,7 @@ class TestStagedConcolicEval extends FunSuite { // Do concolic execution with snapshot reuse val exe = s"$cppFile.exe" val exploreTreeFile = s"$filename.tree.dot" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") println(s"Running compiled concolic execution with snapshot reuse: $exe") val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! println(result) @@ -31,7 +31,7 @@ class TestStagedConcolicEval extends FunSuite { // Do concolic execution without snapshot reuse val exe = s"$cppFile.noreuse.exe" val exploreTreeFile = s"$filename.noreuse.tree.dot" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, false, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, false, optimizeLevel=0, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT") println(s"Running compiled concolic execution without snapshot reuse: $exe") val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! println(result) @@ -51,7 +51,7 @@ class TestStagedConcolicEval extends FunSuite { val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" val exe = s"$cppFile.exe" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, "NO_INFO", "RUN_ONCE") + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, "NO_INFO", "RUN_ONCE") import sys.process._ val result = s"./$exe".!! From e4ac385aa2b0ac2099b03790bf63cf3c525d6341 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 6 Oct 2025 21:54:54 -0400 Subject: [PATCH 47/82] add an option to use immutable data structure --- headers/wasm/config.hpp | 8 +++ headers/wasm/profile.hpp | 2 +- headers/wasm/symbolic_rt.hpp | 100 ++++++++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/headers/wasm/config.hpp b/headers/wasm/config.hpp index 48a54634..9a34daad 100644 --- a/headers/wasm/config.hpp +++ b/headers/wasm/config.hpp @@ -33,4 +33,12 @@ static const bool REUSE_SNAPSHOT = false; static const bool REUSE_SNAPSHOT = true; #endif +// If we use immutable data structures for symbolic states to reduce the cost of +// copying. +#ifdef USE_IMM +static const bool IMMUTABLE_SYMS = true; +#else +static const bool IMMUTABLE_SYMS = false; +#endif + #endif // CONFIG_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index ec17448a..e453a386 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -1,8 +1,8 @@ #ifndef PROFILE_HPP #define PROFILE_HPP -#include "utils.hpp" #include "config.hpp" +#include "utils.hpp" #include #include #include diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 8ecd207d..98a2a33a 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -5,6 +5,9 @@ #include "config.hpp" #include "controls.hpp" #include "heap_mem_bookkeeper.hpp" +#include "immer/map.hpp" +#include "immer/map_transient.hpp" +#include "immer/vector_transient.hpp" #include "profile.hpp" #include "utils.hpp" #include @@ -238,26 +241,44 @@ class SymStack_t { printf("[Debug] poping from stack, size of symbolic stack is: %zu\n", stack.size()); #endif +#ifdef USE_IMM + auto ret = *(stack.end() - 1); + stack.take(stack.size() - 1); + return ret; +#else auto ret = stack.back(); stack.pop_back(); return ret; +#endif } - SymVal peek() { return stack.back(); } + SymVal peek() { return *(stack.end() - 1); } std::monostate shift(int32_t offset, int32_t size) { auto n = stack.size(); for (size_t i = n - size; i < n; ++i) { assert(i - offset >= 0); +#ifdef USE_IMM + stack.set(i - offset, stack[i]); +#else stack[i - offset] = stack[i]; +#endif } +#ifdef USE_IMM + stack.take(n - offset); +#else stack.resize(n - offset); +#endif return std::monostate(); } void reset() { - // Reset the symbolic stack +// Reset the symbolic stack +#ifdef USE_IMM + stack = immer::vector_transient(); +#else stack.clear(); +#endif } size_t size() const { return stack.size(); } @@ -265,20 +286,36 @@ class SymStack_t { SymVal operator[](size_t index) const { return stack[index]; } private: +#ifdef USE_IMM + immer::vector_transient stack; +#else std::vector stack; +#endif }; static SymStack_t SymStack; class SymFrames_t { + public: void pushFrame(int size) { // Push a new frame with the given size +#ifdef USE_IMM + for (int i = 0; i < size; ++i) { + stack.push_back(SymVal()); + } +#else stack.resize(size + stack.size()); +#endif } std::monostate popFrame(int size) { // Pop the frame of the given size + +#ifdef USE_IMM + stack.take(stack.size() - size); +#else stack.resize(stack.size() - size); +#endif return std::monostate(); } @@ -291,12 +328,21 @@ class SymFrames_t { void set(int index, SymVal val) { // Set the symbolic value at the given index assert(val.symptr != nullptr); +#ifdef USE_IMM + stack.set(stack.size() - 1 - index, val); +#else stack[stack.size() - 1 - index] = val; +#endif } void reset() { // Reset the symbolic frames + +#ifdef USE_IMM + stack = immer::vector_transient(); +#else stack.clear(); +#endif } size_t size() const { return stack.size(); } @@ -304,7 +350,11 @@ class SymFrames_t { SymVal operator[](size_t index) const { return stack[index]; } private: +#ifdef USE_IMM + immer::vector_transient stack; +#else std::vector stack; +#endif }; struct NodeBox; @@ -312,19 +362,45 @@ struct SymEnv_t; class SymMemory_t { public: +#ifdef USE_IMM + immer::map_transient memory; +#else std::unordered_map memory; +#endif SymVal loadSymByte(int32_t addr) { - // if the address is not in the memory, it must be a zero-initialized memory +// if the address is not in the memory, it must be a zero-initialized memory +#ifdef USE_IMM auto it = memory.find(addr); - SymVal s = (it != memory.end()) - ? it->second - : SymVal(SymBookKeeper.allocate(8, 0)); + if (it != nullptr) { + return *it; + } else { + auto s = SymVal(ZeroByte); + return s; + } +#else + auto it = memory.find(addr); + SymVal s = (it != memory.end()) ? it->second : SymVal(ZeroByte); return s; +#endif } SymVal loadSym(int32_t base, int32_t offset) { // calculate the real address + +#ifdef USE_IMM + int32_t addr = base + offset; + auto it = memory.find(addr); + SymVal s0 = it ? *it : SymVal(ZeroByte); + it = memory.find(addr + 1); + SymVal s1 = it ? *it : SymVal(ZeroByte); + it = memory.find(addr + 2); + SymVal s2 = it ? *it : SymVal(ZeroByte); + it = memory.find(addr + 3); + SymVal s3 = it ? *it : SymVal(ZeroByte); + + return s3.concat(s2).concat(s1).concat(s0); +#else int32_t addr = base + offset; auto it = memory.find(addr); SymVal s0 = (it != memory.end()) ? it->second : SymVal(ZeroByte); @@ -336,6 +412,7 @@ class SymMemory_t { SymVal s3 = (it != memory.end()) ? it->second : SymVal(ZeroByte); return s3.concat(s2).concat(s1).concat(s0); +#endif } // when loading a symval, we need to concat 4 symbolic values @@ -349,15 +426,26 @@ class SymMemory_t { SymVal s1 = value.extract(2, 2); SymVal s2 = value.extract(3, 3); SymVal s3 = value.extract(4, 4); +#ifdef USE_IMM + memory.set(addr, s0); + memory.set(addr + 1, s1); + memory.set(addr + 2, s2); + memory.set(addr + 3, s3); +#else memory[addr] = s0; memory[addr + 1] = s1; memory[addr + 2] = s2; memory[addr + 3] = s3; +#endif return std::monostate{}; } std::monostate reset() { +#ifdef USE_IMM + memory = immer::map_transient(); +#else memory.clear(); +#endif return std::monostate{}; } }; From 6bae60f4c11ac90f17464f34fc3fb2802ec29cf1 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 6 Oct 2025 22:48:18 -0400 Subject: [PATCH 48/82] a simple test case to show immutable's improvements --- .../wasm/staged/long-trivial-execution.wat | 54 +++++++++++++++++++ .../genwasym/TestStagedConcolicEval.scala | 21 +++++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 benchmarks/wasm/staged/long-trivial-execution.wat diff --git a/benchmarks/wasm/staged/long-trivial-execution.wat b/benchmarks/wasm/staged/long-trivial-execution.wat new file mode 100644 index 00000000..2a23f007 --- /dev/null +++ b/benchmarks/wasm/staged/long-trivial-execution.wat @@ -0,0 +1,54 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32))) + (import "console" "assert" (func (type 1))) + (func (;1;) (type 0) + (local i32 i32) + i32.const 1 + local.set 0 + i32.const 0 + local.set 1 + block + loop + local.get 0 + i32.const 10000 + i32.ge_s + br_if 1 + local.get 1 + i32.const 0 + i32.add + local.set 1 + local.get 0 + i32.const 1 + i32.add + local.set 0 + br 0 + end + end + i32.const 10000 + local.set 0 + i32.const 0 + local.set 1 + block + loop + local.get 0 + i32.eqz + br_if 1 ;; break if counter == 0 + local.get 1 + i32.const 0 + i32.sub ;; acc - 0 (no change) + local.set 1 + local.get 0 + i32.const 1 + i32.sub + local.set 0 ;; counter-- + br 0 ;; repeat loop + end + end + local.get 1 + if + i32.const 0 + call 0 + end + ) + (start 1)) diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 68009388..6a505f14 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -37,6 +37,16 @@ class TestStagedConcolicEval extends FunSuite { println(result) exploreTreeFile } + val exploreTreeFileImm = { + // Do concolic execution with immutable data structure and snapshot reuse + val exe = s"$cppFile.imm.exe" + val exploreTreeFile = s"$filename.imm.tree.dot" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, if (exitByCoverage) "BY_COVERAGE" else "EARLY_EXIT", "USE_IMM") + println(s"Running compiled concolic execution with immutable data structure and snapshot reuse: $exe") + val result = Process(s"./$exe", None, "TREE_FILE" -> exploreTreeFile).!! + println(result) + exploreTreeFile + } // The explore tree generated by two executions should be same import java.nio.file.Files assert( @@ -44,6 +54,11 @@ class TestStagedConcolicEval extends FunSuite { sameElements Files.readAllBytes(java.nio.file.Paths.get(exploreTreeFileNoReuse)), s"Explore trees $exploreTreeFile and $exploreTreeFileNoReuse are different!" ) + assert( + Files.readAllBytes(java.nio.file.Paths.get(exploreTreeFile)) + sameElements Files.readAllBytes(java.nio.file.Paths.get(exploreTreeFileImm)), + s"Explore trees $exploreTreeFile and $exploreTreeFileImm are different!" + ) } // only test concrete execution and its result @@ -51,7 +66,7 @@ class TestStagedConcolicEval extends FunSuite { val moduleInst = ModuleInstance(Parser.parseFile(filename)) val cppFile = s"$filename.cpp" val exe = s"$cppFile.exe" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, "NO_INFO", "RUN_ONCE") + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, "NO_INFO", "RUN_ONCE", "USE_IMM") import sys.process._ val result = s"./$exe".!! @@ -98,6 +113,10 @@ class TestStagedConcolicEval extends FunSuite { } test("btree-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat", exitByCoverage = true) } + test("long-trivial-execution-concrete") { + // This is a example to show how much performance improvement we can get by immutable data structure + testFileConcreteCpp("./benchmarks/wasm/staged/long-trivial-execution.wat", None) + } test("return-poly - concrete") { testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) From 46b8a85da96132a027deb2f17cf0e4db2f40c429 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 12 Oct 2025 05:10:56 +0800 Subject: [PATCH 49/82] add a benchmark testcase --- benchmarks/wasm/compare_wasp/Makefile | 16 + benchmarks/wasm/compare_wasp/large-branch.wat | 591 ++++++++++++++++++ headers/wasm/concolic_driver.hpp | 3 +- headers/wasm/concrete_rt.hpp | 16 +- headers/wasm/config.hpp | 18 +- headers/wasm/profile.hpp | 90 ++- headers/wasm/smt_solver.hpp | 37 +- headers/wasm/symbolic_rt.hpp | 12 +- .../genwasym/TestStagedConcolicEval.scala | 3 + 9 files changed, 724 insertions(+), 62 deletions(-) create mode 100644 benchmarks/wasm/compare_wasp/Makefile create mode 100644 benchmarks/wasm/compare_wasp/large-branch.wat diff --git a/benchmarks/wasm/compare_wasp/Makefile b/benchmarks/wasm/compare_wasp/Makefile new file mode 100644 index 00000000..c9cc74ae --- /dev/null +++ b/benchmarks/wasm/compare_wasp/Makefile @@ -0,0 +1,16 @@ +.PHONY: all run clean + +all: large-branch.wat.cpp.imm.noreuse.exe large-branch.wat.cpp.imm.exe + +large-branch.wat.cpp.imm.noreuse.exe: large-branch.wat.cpp + g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.noreuse.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 -DNO_REUSE + +large-branch.wat.cpp.imm.exe: large-branch.wat.cpp + g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 + +run: all + ./large-branch.wat.cpp.imm.noreuse.exe + ./large-branch.wat.cpp.imm.exe + +clean: + rm -f *.exe \ No newline at end of file diff --git a/benchmarks/wasm/compare_wasp/large-branch.wat b/benchmarks/wasm/compare_wasp/large-branch.wat new file mode 100644 index 00000000..76e40191 --- /dev/null +++ b/benchmarks/wasm/compare_wasp/large-branch.wat @@ -0,0 +1,591 @@ +(module + (type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (type (;1;) (func (result i32))) + (import "spectest" "print_i32" (func (;0;) (param i32))) + + (func (;1;) (type 0) (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + local.get 0 + i32.const 0 + i32.gt_s + if ;; label = @1 + local.get 7 + local.get 13 + i32.add + i32.const 13 + i32.add + local.set 0 + end + local.get 1 + i32.const 1 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 7 + i32.add + i32.const 35 + i32.add + local.set 1 + end + local.get 2 + i32.const 2 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 4 + i32.add + i32.const 69 + i32.add + local.set 2 + end + local.get 3 + i32.const 3 + i32.gt_s + if ;; label = @1 + local.get 13 + local.get 14 + i32.add + i32.const 91 + i32.add + local.set 3 + end + local.get 4 + i32.const 4 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 10 + i32.add + i32.const 47 + i32.add + local.set 4 + end + local.get 5 + i32.const 5 + i32.gt_s + if ;; label = @1 + local.get 15 + local.get 6 + i32.add + i32.const 74 + i32.add + local.set 5 + end + local.get 6 + i32.const 6 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 8 + i32.add + i32.const 15 + i32.add + local.set 6 + end + local.get 7 + i32.const 7 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 9 + i32.add + i32.const 34 + i32.add + local.set 7 + end + local.get 8 + i32.const 8 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 12 + i32.add + i32.const 57 + i32.add + local.set 8 + end + local.get 9 + i32.const 9 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 11 + i32.add + i32.const 3 + i32.add + local.set 9 + end + local.get 10 + i32.const 10 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 6 + i32.add + i32.const 21 + i32.add + local.set 10 + end + local.get 11 + i32.const 11 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 5 + i32.add + i32.const 72 + i32.add + local.set 11 + end + local.get 12 + i32.const 12 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 6 + i32.add + i32.const 55 + i32.add + local.set 12 + end + local.get 13 + i32.const 13 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 3 + i32.add + i32.const 12 + i32.add + local.set 13 + end + local.get 14 + i32.const 14 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 12 + i32.add + i32.const 69 + i32.add + local.set 14 + end + local.get 15 + i32.const 15 + i32.gt_s + if ;; label = @1 + local.get 18 + local.get 5 + i32.add + i32.const 92 + i32.add + local.set 15 + end + local.get 16 + i32.const 16 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 12 + i32.add + i32.const 39 + i32.add + local.set 16 + end + local.get 17 + i32.const 17 + i32.gt_s + if ;; label = @1 + local.get 15 + local.get 8 + i32.add + i32.const 39 + i32.add + local.set 17 + end + local.get 18 + i32.const 18 + i32.gt_s + if ;; label = @1 + local.get 17 + local.get 3 + i32.add + i32.const 64 + i32.add + local.set 18 + end + local.get 19 + i32.const 19 + i32.gt_s + if ;; label = @1 + local.get 11 + local.get 5 + i32.add + i32.const 78 + i32.add + local.set 19 + end + local.get 6 + i32.const 6 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 8 + i32.add + i32.const 15 + i32.add + local.set 6 + end + local.get 7 + i32.const 7 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 9 + i32.add + i32.const 34 + i32.add + local.set 7 + end + local.get 8 + i32.const 8 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 12 + i32.add + i32.const 57 + i32.add + local.set 8 + end + local.get 9 + i32.const 9 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 11 + i32.add + i32.const 3 + i32.add + local.set 9 + end + local.get 10 + i32.const 10 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 6 + i32.add + i32.const 21 + i32.add + local.set 10 + end + local.get 11 + i32.const 11 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 5 + i32.add + i32.const 72 + i32.add + local.set 11 + end + local.get 12 + i32.const 12 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 6 + i32.add + i32.const 55 + i32.add + local.set 12 + end + local.get 13 + i32.const 13 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 3 + i32.add + i32.const 12 + i32.add + local.set 13 + end + local.get 14 + i32.const 14 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 12 + i32.add + i32.const 69 + i32.add + local.set 14 + end + local.get 15 + i32.const 15 + i32.gt_s + if ;; label = @1 + local.get 18 + local.get 5 + i32.add + i32.const 92 + i32.add + local.set 15 + end + local.get 16 + i32.const 16 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 12 + i32.add + i32.const 39 + i32.add + local.set 16 + end + local.get 1 + local.get 2 + i32.add + local.get 3 + i32.add + local.get 4 + i32.add + local.get 5 + i32.add + local.get 6 + i32.add + local.get 7 + i32.add + local.get 8 + i32.add + local.get 9 + i32.add + local.get 10 + i32.add + local.get 11 + i32.add + local.get 12 + i32.add + local.get 13 + i32.add + local.get 14 + i32.add + local.get 15 + i32.add + local.get 16 + i32.add + local.get 17 + i32.add + local.get 18 + i32.add + local.get 19 + i32.add) + (func (;2;) (type 1) (result i32) + i32.const 0 + i32.symbolic + i32.const 1 + i32.symbolic + i32.const 2 + i32.symbolic + i32.const 3 + i32.symbolic + i32.const 4 + i32.symbolic + i32.const 5 + i32.symbolic + i32.const 6 + i32.symbolic + i32.const 7 + i32.symbolic + i32.const 8 + i32.symbolic + i32.const 9 + i32.symbolic + i32.const 10 + i32.const 11 + i32.const 12 + i32.const 13 + i32.const 14 + i32.const 15 + i32.const 16 + i32.const 17 + i32.const 18 + i32.const 19 + call 3) + (func (;3;) (type 0) (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + local.get 0 + i32.const 0 + i32.gt_s + if ;; label = @1 + local.get 7 + local.get 13 + i32.add + i32.const 13 + i32.add + local.set 0 + end + local.get 1 + i32.const 1 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 7 + i32.add + i32.const 35 + i32.add + local.set 1 + end + local.get 2 + i32.const 2 + i32.gt_s + if ;; label = @1 + local.get 0 + local.get 4 + i32.add + i32.const 69 + i32.add + local.set 2 + end + local.get 3 + i32.const 3 + i32.gt_s + if ;; label = @1 + local.get 13 + local.get 14 + i32.add + i32.const 91 + i32.add + local.set 3 + end + local.get 4 + i32.const 4 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 10 + i32.add + i32.const 47 + i32.add + local.set 4 + end + local.get 5 + i32.const 5 + i32.gt_s + if ;; label = @1 + local.get 15 + local.get 6 + i32.add + i32.const 74 + i32.add + local.set 5 + end + local.get 6 + i32.const 6 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 8 + i32.add + i32.const 15 + i32.add + local.set 6 + end + local.get 6 + i32.const 6 + i32.gt_s + if ;; label = @1 + local.get 19 + local.get 8 + i32.add + i32.const 15 + i32.add + local.set 6 + end + local.get 7 + i32.const 7 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 9 + i32.add + i32.const 34 + i32.add + local.set 7 + end + local.get 8 + i32.const 8 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 12 + i32.add + i32.const 57 + i32.add + local.set 8 + end + local.get 9 + i32.const 9 + i32.gt_s + if ;; label = @1 + local.get 10 + local.get 11 + i32.add + i32.const 3 + i32.add + local.set 9 + end + local.get 10 + i32.const 10 + i32.gt_s + if ;; label = @1 + local.get 6 + local.get 6 + i32.add + i32.const 21 + i32.add + local.set 10 + end + local.get 1 + local.get 2 + i32.add + local.get 3 + i32.add + local.get 4 + i32.add + local.get 5 + i32.add + local.get 6 + i32.add + local.get 7 + i32.add + local.get 8 + i32.add + local.get 9 + i32.add + local.get 10 + i32.add + local.get 11 + i32.add + local.get 12 + i32.add + local.get 13 + i32.add + local.get 14 + i32.add + local.get 15 + i32.add + local.get 16 + i32.add + local.get 17 + i32.add + local.get 18 + i32.add + local.get 19 + i32.add + ) + (export "f" (func 1)) + (export "main" (func 2)) + (start 2)) + diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 37ef4004..84e05c84 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -100,10 +100,9 @@ inline void ConcolicDriver::main_exploration_loop() { GENSYM_INFO(SymEnv.to_string()); if (auto snapshot_node = dynamic_cast(node->node.get())) { assert(REUSE_SNAPSHOT); - auto timer = ManagedTimer(); snapshot_node->get_snapshot().resume_execution(SymEnv, node); } else { - auto timer = ManagedTimer(); + auto timer = ManagedTimer(TimeProfileKind::INSTR); reset_stacks(); ExploreTree.reset_cursor(); entrypoint(); diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index c75c0215..ea321f45 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -60,21 +60,21 @@ class Stack_t { } std::monostate push(Num &&num) { - Profile.step(ProfileKind::PUSH); + Profile.step(StepProfileKind::PUSH); stack_ptr[count] = num; count++; return std::monostate{}; } std::monostate push(Num &num) { - Profile.step(ProfileKind::PUSH); + Profile.step(StepProfileKind::PUSH); stack_ptr[count] = num; count++; return std::monostate{}; } Num pop() { - Profile.step(ProfileKind::POP); + Profile.step(StepProfileKind::POP); #ifdef DEBUG assert(count > 0 && "Stack underflow"); printf("[Debug] popping a value %ld from stack, size of concrete stack is: " @@ -87,7 +87,7 @@ class Stack_t { } Num peek() { - Profile.step(ProfileKind::PEEK); + Profile.step(StepProfileKind::PEEK); #ifdef DEBUG if (count == 0) { throw std::runtime_error("Stack underflow"); @@ -99,7 +99,7 @@ class Stack_t { int32_t size() { return count; } void shift(int32_t offset, int32_t size) { - Profile.step(ProfileKind::SHIFT); + Profile.step(StepProfileKind::SHIFT); #ifdef DEBUG if (offset < 0) { throw std::out_of_range("Invalid offset: " + std::to_string(offset)); @@ -168,13 +168,13 @@ class Frames_t { } Num get(std::int32_t index) { - Profile.step(ProfileKind::GET); + Profile.step(StepProfileKind::GET); auto ret = stack_ptr[count - 1 - index]; return ret; } void set(std::int32_t index, Num num) { - Profile.step(ProfileKind::SET); + Profile.step(StepProfileKind::SET); stack_ptr[count - 1 - index] = num; } @@ -273,7 +273,7 @@ struct Memory_t { // grow memory by delta bytes when bytes > 0. return -1 if failed, return old // size when success int32_t grow(int32_t delta) { - Profile.step(ProfileKind::MEM_GROW); + Profile.step(StepProfileKind::MEM_GROW); if (delta <= 0) { return page_count * pagesize; } diff --git a/headers/wasm/config.hpp b/headers/wasm/config.hpp index 9a34daad..76be60ac 100644 --- a/headers/wasm/config.hpp +++ b/headers/wasm/config.hpp @@ -3,12 +3,20 @@ // This file contains configuration settings for the concolic execution -// If ENABLE_PROFILE defined, the compiled program will collect and print -// profiling information -#ifdef ENABLE_PROFILE -const bool PROFILE_ENABLED = true; +// If ENABLE_PROFILE_STEP defined, the compiled program will collect and print +// profiling how much steps of each data structure's operations are executed +#ifdef ENABLE_PROFILE_STEP +const bool PROFILE_STEP = true; #else -const bool PROFILE_ENABLED = false; +const bool PROFILE_STEP = false; +#endif + +// If ENABLE_PROFILE_TIME defined, the compiled program will collect and print +// the profile of time spent in main loop and constraint solving +#ifdef ENABLE_PROFILE_TIME +const bool PROFILE_TIME = true; +#else +const bool PROFILE_TIME = false; #endif // This variable define when concolic execution will stop diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index e453a386..ee0bef38 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -8,7 +8,7 @@ #include #include -enum class ProfileKind { +enum class StepProfileKind { PUSH, POP, PEEK, @@ -24,74 +24,100 @@ enum class ProfileKind { // number of kinds of operations }; +enum class TimeProfileKind { + INSTR, + SOLVER, + RESUME_SNAPSHOT, + TimeOperationCount // keep this as the last element, this is used to get the + // number of kinds of operations +}; + class Profile_t { public: Profile_t() : step_count(0) {} std::monostate step() { - if (PROFILE_ENABLED) + if (PROFILE_STEP) step_count++; return std::monostate(); } - std::monostate step(ProfileKind op) { - if (PROFILE_ENABLED) + std::monostate step(StepProfileKind op) { + if (PROFILE_STEP) op_count[static_cast(op)]++; return std::monostate(); } void print_summary() { - if (PROFILE_ENABLED) { + if (PROFILE_STEP) { std::cout << "Profile Summary:" << std::endl; std::cout << "Total PUSH operations: " - << op_count[static_cast(ProfileKind::PUSH)] + << op_count[static_cast(StepProfileKind::PUSH)] << std::endl; std::cout << "Total POP operations: " - << op_count[static_cast(ProfileKind::POP)] + << op_count[static_cast(StepProfileKind::POP)] << std::endl; std::cout << "Total PEEK operations: " - << op_count[static_cast(ProfileKind::PEEK)] + << op_count[static_cast(StepProfileKind::PEEK)] << std::endl; std::cout << "Total SHIFT operations: " - << op_count[static_cast(ProfileKind::SHIFT)] + << op_count[static_cast(StepProfileKind::SHIFT)] << std::endl; std::cout << "Total SET operations: " - << op_count[static_cast(ProfileKind::SET)] + << op_count[static_cast(StepProfileKind::SET)] << std::endl; std::cout << "Total GET operations: " - << op_count[static_cast(ProfileKind::GET)] + << op_count[static_cast(StepProfileKind::GET)] << std::endl; std::cout << "Total BINARY operations: " - << op_count[static_cast(ProfileKind::BINARY)] - << std::endl; - std::cout << "Total TREE_FILL operations: " - << op_count[static_cast(ProfileKind::TREE_FILL)] - << std::endl; - std::cout << "Total CURSOR_MOVE operations: " - << op_count[static_cast(ProfileKind::CURSOR_MOVE)] + << op_count[static_cast(StepProfileKind::BINARY)] << std::endl; + std::cout + << "Total TREE_FILL operations: " + << op_count[static_cast(StepProfileKind::TREE_FILL)] + << std::endl; + std::cout + << "Total CURSOR_MOVE operations: " + << op_count[static_cast(StepProfileKind::CURSOR_MOVE)] + << std::endl; std::cout << "Total other instructions executed: " << step_count << std::endl; std::cout << "Total MEM_GROW operations: " - << op_count[static_cast(ProfileKind::MEM_GROW)] + << op_count[static_cast(StepProfileKind::MEM_GROW)] + << std::endl; + std::cout << "Total SNAPSHOT_CREATE operations: " + << op_count[static_cast( + StepProfileKind::SNAPSHOT_CREATE)] << std::endl; - std::cout - << "Total SNAPSHOT_CREATE operations: " - << op_count[static_cast(ProfileKind::SNAPSHOT_CREATE)] - << std::endl; std::cout << "Total time for instruction execution (s): " << std::setprecision(15) << execution_time << std::endl; } + if (PROFILE_TIME) { + std::cout << "Time Profile Summary:" << std::endl; + std::cout << "Total time in instruction execution (s): " + << std::setprecision(15) + << time_count[static_cast(TimeProfileKind::INSTR)] + << std::endl; + std::cout << "Total time in solver (s): " << std::setprecision(15) + << time_count[static_cast(TimeProfileKind::SOLVER)] + << std::endl; + std::cout << "Total time in resuming from snapshot (s): " + << std::setprecision(15) + << time_count[static_cast( + TimeProfileKind::RESUME_SNAPSHOT)] + << std::endl; + } } // record the time spent in main instruction execution, in seconds - void add_instruction_time(double time) { -#ifdef ENABLE_PROFILE - execution_time += time; -#endif + void add_instruction_time(TimeProfileKind kind, double time) { + time_count[static_cast(kind)] += time; } private: int step_count; - std::array(ProfileKind::OperationCount)> + std::array(StepProfileKind::OperationCount)> op_count; + std::array(TimeProfileKind::TimeOperationCount)> + time_count; double execution_time = 0.0; }; @@ -99,14 +125,18 @@ static Profile_t Profile; class ManagedTimer { public: - ManagedTimer() { start = std::chrono::high_resolution_clock::now(); } + ManagedTimer() = delete; + ManagedTimer(TimeProfileKind kind) : kind(kind) { + start = std::chrono::high_resolution_clock::now(); + } ~ManagedTimer() { auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = end - start; - Profile.add_instruction_time(elapsed.count()); + Profile.add_instruction_time(kind, elapsed.count()); } private: + TimeProfileKind kind; std::chrono::high_resolution_clock::time_point start; }; diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 8625a65d..5df683f7 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -4,6 +4,7 @@ #include "concrete_rt.hpp" #include "symbolic_rt.hpp" #include "utils.hpp" +#include "wasm/profile.hpp" #include "z3++.h" #include #include @@ -15,20 +16,17 @@ class Solver { public: Solver() {} std::optional solve(const std::vector &conditions) { - // make an conjunction of all conditions - z3::expr conjunction = z3_ctx.bool_val(true); - for (const auto &cond : conditions) { - auto z3_cond = build_z3_expr(cond); - conjunction = conjunction && z3_cond != z3_ctx.bv_val(0, 32); - } -#ifdef DEBUG - std::cout << "Symbolic conditions size: " << conditions.size() << std::endl; - std::cout << "Solving conditions: " << conjunction << std::endl; -#endif - // call z3 to solve the condition z3::solver z3_solver(z3_ctx); - z3_solver.add(conjunction); - switch (z3_solver.check()) { + z3::check_result solver_result; + { + // make an conjunction of all conditions + auto conjunction = to_z3_conjunction(conditions); + // call z3 to solve the condition + auto timer = ManagedTimer(TimeProfileKind::SOLVER); + z3_solver.add(conjunction); // NOTE: half of the solver time is spent in solver.add + solver_result = z3_solver.check(); + } + switch (solver_result) { case z3::unsat: return std::nullopt; // No solution found case z3::sat: { @@ -58,6 +56,19 @@ class Solver { } private: + z3::expr to_z3_conjunction(const std::vector &conditions) { + z3::expr conjunction = z3_ctx.bool_val(true); + for (const auto &cond : conditions) { + auto z3_cond = build_z3_expr(cond); + conjunction = conjunction && z3_cond != z3_ctx.bv_val(0, 32); + } +#ifdef DEBUG + std::cout << "Symbolic conditions size: " << conditions.size() << std::endl; + std::cout << "Solving conditions: " << conjunction << std::endl; +#endif + return conjunction; + } + z3::context z3_ctx; z3::expr build_z3_expr(const SymVal &sym_val); }; diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 98a2a33a..35e19bd8 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -761,7 +761,7 @@ inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont, SymStack_t stack, SymFrames_t frames, SymMemory_t memory) : stack(std::move(stack)), frames(std::move(frames)), memory(std::move(memory)), cont(cont), mcont(mcont) { - Profile.step(ProfileKind::SNAPSHOT_CREATE); + Profile.step(StepProfileKind::SNAPSHOT_CREATE); #ifdef DEBUG std::cout << "Creating snapshot of size " << stack.size() << std::endl; #endif @@ -806,7 +806,7 @@ class ExploreTree_t { } std::monostate moveCursor(bool branch, Snapshot_t snapshot) { - Profile.step(ProfileKind::CURSOR_MOVE); + Profile.step(StepProfileKind::CURSOR_MOVE); assert(cursor != nullptr); auto if_else_node = dynamic_cast(cursor->node.get()); assert( @@ -1074,9 +1074,13 @@ inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, SymStack = stack; SymFrames = frames; SymMemory = memory; - // Restore the concrete states from the symbolic states - resume_conc_states(stack, frames, memory, Stack, Frames, Memory, sym_env); + { + auto timer = ManagedTimer(TimeProfileKind::RESUME_SNAPSHOT); + // Restore the concrete states from the symbolic states + resume_conc_states(stack, frames, memory, Stack, Frames, Memory, sym_env); + } // Resume execution from the continuation + auto timer = ManagedTimer(TimeProfileKind::INSTR); return cont(mcont); } diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 6a505f14..3bee9f75 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -171,4 +171,7 @@ class TestStagedConcolicEval extends FunSuite { testFileConcreteCpp("./benchmarks/wasm/staged/brtable.wat") } + test("large-branch-concrete") { + testFileConcreteCpp("./benchmarks/wasm/compare_wasp/large-branch.wat") + } } From db4925140d7df371bb25ec6fce1ff8be08d5f868 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 12 Oct 2025 06:12:50 +0800 Subject: [PATCH 50/82] a pool to store symbolic concrete --- headers/wasm/symbolic_rt.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 35e19bd8..798adf4d 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -120,8 +120,16 @@ static SymVal make_symbolic(int index) { return SymVal(SymBookKeeper.allocate(index)); } +static std::unordered_map concrete_pool; + inline SymVal Concrete(Num num) { - return SymVal(SymBookKeeper.allocate(num)); + if (concrete_pool.find(num.toInt()) != concrete_pool.end()) { + return concrete_pool[num.toInt()]; + } + + auto new_val = SymVal(SymBookKeeper.allocate(num)); + concrete_pool[num.toInt()] = new_val; + return new_val; } // Extract is different from other operations, it only has one symbolic operand, From b4d18ba03bc2a08dd0471fab89ce43779f92704f Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sun, 12 Oct 2025 06:16:36 +0800 Subject: [PATCH 51/82] a example to show when snapshot is highly effective --- .../wasm/compare_wasp/small-snapshot.wat | 22301 ++++++++++++++++ .../genwasym/TestStagedConcolicEval.scala | 4 + 2 files changed, 22305 insertions(+) create mode 100644 benchmarks/wasm/compare_wasp/small-snapshot.wat diff --git a/benchmarks/wasm/compare_wasp/small-snapshot.wat b/benchmarks/wasm/compare_wasp/small-snapshot.wat new file mode 100644 index 00000000..991a3d25 --- /dev/null +++ b/benchmarks/wasm/compare_wasp/small-snapshot.wat @@ -0,0 +1,22301 @@ +(module + (type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (type (;1;) (func (result i32))) + (import "spectest" "print_i32" (func (;0;) (param i32))) + + (func (;1;) (type 0) (result i32) + i32.const 0 + i32.symbolic + call 2 + if (result i32) + i32.const 42 + else + i32.const 19 + end) + + (func (;2;) (param i32) (result i32) + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + i32.const 3 + drop + local.get 0) + (export "f" (func 2)) + (export "main" (func 1)) + (start 1)) + diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 3bee9f75..86f55daa 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -174,4 +174,8 @@ class TestStagedConcolicEval extends FunSuite { test("large-branch-concrete") { testFileConcreteCpp("./benchmarks/wasm/compare_wasp/large-branch.wat") } + + test("small-snapshot-concrete") { + testFileConcreteCpp("./benchmarks/wasm/compare_wasp/small-snapshot.wat", Some("main")) + } } From 960aacbb51fbce95c16c9f4abfebbe4910a713b6 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 18 Oct 2025 19:47:47 +0800 Subject: [PATCH 52/82] some infra to support the cost model to decide if we should create snapshot --- headers/wasm/concolic_driver.hpp | 26 +-- headers/wasm/config.hpp | 6 + headers/wasm/controls.hpp | 7 + headers/wasm/profile.hpp | 27 +++ headers/wasm/symbolic_rt.hpp | 201 +++++++++++++++--- .../scala/wasm/StagedConcolicMiniWasm.scala | 61 ++++-- 6 files changed, 261 insertions(+), 67 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 84e05c84..80ff38d5 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -84,6 +84,11 @@ inline void ConcolicDriver::main_exploration_loop() { continue; } + if (INTERACTIVE_MODE) { + std::cout << "Press Enter to continue to the next path..." << std::endl; + std::cin.get(); + } + auto cond = node->collect_path_conds(); auto result = solver.solve(cond); if (!result.has_value()) { @@ -98,15 +103,7 @@ inline void ConcolicDriver::main_exploration_loop() { try { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); - if (auto snapshot_node = dynamic_cast(node->node.get())) { - assert(REUSE_SNAPSHOT); - snapshot_node->get_snapshot().resume_execution(SymEnv, node); - } else { - auto timer = ManagedTimer(TimeProfileKind::INSTR); - reset_stacks(); - ExploreTree.reset_cursor(); - entrypoint(); - } + { node->reach_here(entrypoint); } GENSYM_INFO("Execution finished successfully with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); @@ -140,17 +137,6 @@ inline void ConcolicDriver::run() { Profile.print_summary(); } -static std::monostate reset_stacks() { - Stack.reset(); - SymStack.reset(); - Frames.reset(); - SymFrames.reset(); - Memory.reset(); - SymMemory.reset(); - initRand(); - return std::monostate{}; -} - static void start_concolic_execution_with( std::function entrypoint, int branchCount) { diff --git a/headers/wasm/config.hpp b/headers/wasm/config.hpp index 76be60ac..a9c8d5a1 100644 --- a/headers/wasm/config.hpp +++ b/headers/wasm/config.hpp @@ -49,4 +49,10 @@ static const bool IMMUTABLE_SYMS = true; static const bool IMMUTABLE_SYMS = false; #endif +#ifdef INTERACTIVE +static const bool INTERACTIVE_MODE = true; +#else +static const bool INTERACTIVE_MODE = false; +#endif + #endif // CONFIG_HPP \ No newline at end of file diff --git a/headers/wasm/controls.hpp b/headers/wasm/controls.hpp index 513f0692..97ba0130 100644 --- a/headers/wasm/controls.hpp +++ b/headers/wasm/controls.hpp @@ -9,4 +9,11 @@ using MCont_t = std::function; using Cont_t = std::function; +struct Control { + Cont_t cont; + MCont_t mcont; + + Control(Cont_t cont, MCont_t mcont) : cont(cont), mcont(mcont) {} +}; + #endif // WASM_CONTROLS_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index ee0bef38..bc4ce911 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -28,6 +28,7 @@ enum class TimeProfileKind { INSTR, SOLVER, RESUME_SNAPSHOT, + COUNT_SYM_SIZE, TimeOperationCount // keep this as the last element, this is used to get the // number of kinds of operations }; @@ -103,6 +104,11 @@ class Profile_t { << time_count[static_cast( TimeProfileKind::RESUME_SNAPSHOT)] << std::endl; + std::cout << "Total time in counting symbolic size (s): " + << std::setprecision(15) + << time_count[static_cast( + TimeProfileKind::COUNT_SYM_SIZE)] + << std::endl; } } @@ -140,4 +146,25 @@ class ManagedTimer { std::chrono::high_resolution_clock::time_point start; }; +struct CostManager_t { + int instr_cost; + + CostManager_t() : instr_cost(0) {} + + std::monostate add_instr_cost(int n) { + instr_cost += n; + return {}; + } + + int dump_instr_cost() { + auto cost = instr_cost; + instr_cost = 0; + return normalize_cost(cost); + } + + int normalize_cost(int cost) { return 1 * cost; } +}; + +static CostManager_t CostManager; + #endif // PROFILE_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 798adf4d..1423dcf1 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -27,8 +27,9 @@ class Symbolic { public: - Symbolic() {} // TODO: remove this default constructor later + Symbolic() {} virtual ~Symbolic() = default; // Make Symbolic polymorphic + virtual int size() = 0; }; static int max_id = 0; @@ -39,6 +40,7 @@ class Symbol : public Symbolic { // for now we just assume that only i32 will be used Symbol(int id) : id(id) { max_id = std::max(max_id, id); } int get_id() const { return id; } + int size() override { return 1; } private: int id; @@ -48,16 +50,18 @@ class SymConcrete : public Symbolic { public: Num value; SymConcrete(Num num) : value(num) {} + int size() override { return 1; } }; class SmallBV : public Symbolic { public: - SmallBV(int size, int64_t value) : size(size), value(value) {} - int get_size() const { return size; } + SmallBV(int width, int64_t value) : width(width), value(value) {} + int get_size() const { return width; } int64_t get_value() const { return value; } + int size() override { return 1; } private: - int size; // in bits + int width; // in bits int64_t value; }; struct SymBinary; @@ -111,6 +115,7 @@ struct SymVal { // TODO: add bitwise operations, and use the underlying bitvector theory bool is_concrete() const; + int size() const { return symptr->size(); } private: static SymVal make_binary(Operation op, const SymVal &lhs, const SymVal &rhs); @@ -142,6 +147,7 @@ struct SymExtract : Symbolic { SymExtract(SymVal value, int high, int low) : value(value), high(high), low(low) {} + int size() override { return 1 + value.size(); } }; struct SymBinary : Symbolic { @@ -151,6 +157,7 @@ struct SymBinary : Symbolic { SymBinary(Operation op, SymVal lhs, SymVal rhs) : op(op), lhs(lhs), rhs(rhs) {} + int size() override { return 1 + lhs.size() + rhs.size(); } }; inline SymVal SymVal::add(const SymVal &other) const { @@ -293,6 +300,14 @@ class SymStack_t { SymVal operator[](size_t index) const { return stack[index]; } + int cost_of_copy() const { + int cost = 0; + for (size_t i = 0; i < stack.size(); ++i) { + cost += stack[i].size(); + } + return cost; + } + private: #ifdef USE_IMM immer::vector_transient stack; @@ -357,6 +372,14 @@ class SymFrames_t { SymVal operator[](size_t index) const { return stack[index]; } + int cost_of_copy() const { + int cost = 0; + for (size_t i = 0; i < stack.size(); ++i) { + cost += stack[i].size(); + } + return cost; + } + private: #ifdef USE_IMM immer::vector_transient stack; @@ -456,6 +479,15 @@ class SymMemory_t { #endif return std::monostate{}; } + + int cost_of_copy() const { +#ifdef USE_IMM + // If we use immer, the copy cost should be negligible + return 0; +#else + return memory.size(); +#endif + } }; static SymMemory_t SymMemory; @@ -471,7 +503,9 @@ class Snapshot_t { SymFrames_t get_frames() const { return frames; } SymMemory_t get_memory() const { return memory; } - std::monostate resume_execution(SymEnv_t &sym_env, NodeBox *node) const; + std::monostate resume_execution(NodeBox *node) const; + + static int cost_of_snapshot(); private: SymStack_t stack; @@ -485,13 +519,14 @@ class Snapshot_t { static SymFrames_t SymFrames; static SymFrames_t SymGlobals; -static Snapshot_t makeSnapshot(Cont_t cont, MCont_t mcont) { - if (REUSE_SNAPSHOT) { - return Snapshot_t(cont, mcont, SymStack, SymFrames, SymMemory); - } else { - // create a dummy snapshot, which will not be used - return Snapshot_t(); - } +static Control makeControl(Cont_t cont, MCont_t mcont) { + return Control(cont, mcont); +} + +static Snapshot_t makeSnapshot(Control control) { + // create a snapshot from the current symbolic states and the control + return Snapshot_t(control.cont, control.mcont, SymStack, SymFrames, + SymMemory); } struct Node; @@ -500,6 +535,8 @@ struct NodeBox { explicit NodeBox(NodeBox *parent); std::unique_ptr node; NodeBox *parent; + int cost; + int instr_cost; bool fillIfElseNode(SymVal cond, int id); std::monostate fillFinishedNode(); @@ -508,6 +545,8 @@ struct NodeBox { std::monostate fillSnapshotNode(Snapshot_t snapshot); bool isUnexplored() const; std::vector collect_path_conds(); + int min_cost_of_reaching_here(); + void reach_here(std::function); }; struct Node { @@ -555,10 +594,17 @@ struct IfElseNode : Node { std::unique_ptr true_branch; std::unique_ptr false_branch; int id; + std::optional snapshot; IfElseNode(SymVal cond, NodeBox *parent, int id) : cond(cond), true_branch(std::make_unique(parent)), - false_branch(std::make_unique(parent)), id(id) {} + false_branch(std::make_unique(parent)), id(id), + snapshot(std::nullopt) {} + + IfElseNode(SymVal cond, NodeBox *parent, int id, Snapshot_t snapshot) + : cond(cond), true_branch(std::make_unique(parent)), + false_branch(std::make_unique(parent)), id(id), + snapshot(snapshot) {} std::string to_string() override { std::string result = "IfElseNode {\n"; @@ -622,6 +668,7 @@ struct SnapshotNode : Node { SnapshotNode(Snapshot_t snapshot) : snapshot(snapshot) {} std::string to_string() override { return "SnapshotNode"; } const Snapshot_t &get_snapshot() const { return snapshot; } + Snapshot_t move_out_snapshot() { return std::move(snapshot); } protected: void generate_dot(std::ostream &os, int parent_dot_id, @@ -689,11 +736,15 @@ struct Unreachable : Node { inline NodeBox::NodeBox(NodeBox *parent) : node(std::make_unique()), /* TODO: avoid allocation of unexplored node */ - parent(parent) {} + parent(parent), cost(-1), instr_cost(0) {} inline bool NodeBox::fillIfElseNode(SymVal cond, int id) { // fill the current NodeBox with an ifelse branch node when it's unexplored - if (this->isUnexplored()) { + if (auto ptr = dynamic_cast(node.get())) { + node = + std::make_unique(cond, this, id, ptr->move_out_snapshot()); + return true; + } else if (dynamic_cast(node.get())) { node = std::make_unique(cond, this, id); return true; } @@ -738,8 +789,14 @@ inline std::monostate NodeBox::fillUnreachableNode() { } inline bool NodeBox::isUnexplored() const { - return dynamic_cast(node.get()) != nullptr || - dynamic_cast(node.get()) != nullptr; + assert(node != nullptr); + if (dynamic_cast(node.get()) != nullptr) { + return true; + } + if (dynamic_cast(node.get()) != nullptr) { + return true; + } + return false; } inline std::vector NodeBox::collect_path_conds() { @@ -765,6 +822,25 @@ inline std::vector NodeBox::collect_path_conds() { return result; } +inline int NodeBox::min_cost_of_reaching_here() { + if (cost != -1) { + return cost; + } + + if (auto snapshot = dynamic_cast(node.get())) { + cost = snapshot->get_snapshot().cost_of_snapshot(); + return cost; + } + + if (parent != nullptr) { + auto parent_cost = parent->min_cost_of_reaching_here(); + cost = parent_cost + instr_cost; + return cost; + } + cost = instr_cost; + return cost; +} + inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont, SymStack_t stack, SymFrames_t frames, SymMemory_t memory) : stack(std::move(stack)), frames(std::move(frames)), @@ -775,6 +851,12 @@ inline Snapshot_t::Snapshot_t(Cont_t cont, MCont_t mcont, SymStack_t stack, #endif } +inline int Snapshot_t::cost_of_snapshot() { + auto cost_of_stack_copy = SymStack.cost_of_copy(); + auto cost_of_frame_copy = SymFrames.cost_of_copy(); + auto cost_of_memory_copy = SymMemory.cost_of_copy(); + return cost_of_stack_copy + cost_of_frame_copy + cost_of_memory_copy; +} class ExploreTree_t { public: explicit ExploreTree_t() @@ -813,17 +895,37 @@ class ExploreTree_t { return std::monostate(); } - std::monostate moveCursor(bool branch, Snapshot_t snapshot) { + bool worth_to_create_snapshot() { + // find out the best way to reach the current position via our cost model + auto snapshot_cost = Snapshot_t::cost_of_snapshot(); + auto parent_cost = + cursor->parent ? cursor->parent->min_cost_of_reaching_here() : 0; + auto exec_from_parent_cost = + cursor->min_cost_of_reaching_here() + cursor->instr_cost; + // TODO: return a random result to test the infrastructure, replace this to the + // real cost model later + if (std::rand() % 2 == 0) { + return true; + } else { + return false; + } + } + + std::monostate moveCursor(bool branch, Control control) { Profile.step(StepProfileKind::CURSOR_MOVE); assert(cursor != nullptr); auto if_else_node = dynamic_cast(cursor->node.get()); assert( if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); + int cost_from_parent = CostManager.dump_instr_cost(); if (branch) { true_branch_cov_map[if_else_node->id] = true; if (REUSE_SNAPSHOT) { - if_else_node->false_branch->fillSnapshotNode(snapshot); + if (worth_to_create_snapshot()) { + auto snapshot = makeSnapshot(control); + if_else_node->false_branch->fillSnapshotNode(snapshot); + } } else { // Do nothing, the initial value of the branch is an unexplored node } @@ -831,7 +933,10 @@ class ExploreTree_t { } else { false_branch_cov_map[if_else_node->id] = true; if (REUSE_SNAPSHOT) { - if_else_node->true_branch->fillSnapshotNode(snapshot); + if (worth_to_create_snapshot()) { + auto snapshot = makeSnapshot(control); + if_else_node->true_branch->fillSnapshotNode(snapshot); + } } else { // Do nothing, the initial value of the branch is an unexplored node } @@ -955,6 +1060,41 @@ class SymEnv_t { static SymEnv_t SymEnv; +static std::monostate reset_stacks() { + Stack.reset(); + SymStack.reset(); + Frames.reset(); + SymFrames.reset(); + Memory.reset(); + SymMemory.reset(); + initRand(); + return std::monostate{}; +} + +inline void NodeBox::reach_here(std::function entrypoint) { + // reach the node of exploration tree with given input (symbolic environment) + if (auto snapshot = dynamic_cast(node.get())) { + assert(REUSE_SNAPSHOT); + auto snap = snapshot->get_snapshot(); + snap.resume_execution(this); + } + if (parent == nullptr) { + // if it's the root node, the only way to reach here is to reset everything + // and start a new execution + assert(this == ExploreTree.get_root() && + "Only the root node can have no parent"); + auto timer = ManagedTimer(TimeProfileKind::INSTR); + ExploreTree.reset_cursor(); + reset_stacks(); + entrypoint(); + return; + } + // Reach the parent node, then from the parent node, we can reach here + // TODO: short circuit the lookup + parent->reach_here(entrypoint); + return; +} + struct EvalRes { Num value; int width; // in bits @@ -1072,8 +1212,7 @@ static void resume_conc_states(const SymStack_t &sym_stack, resume_conc_memory(sym_memory, memory, sym_env); } -inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, - NodeBox *node) const { +inline std::monostate Snapshot_t::resume_execution(NodeBox *node) const { // Reset explore tree's cursor ExploreTree.set_cursor(node); @@ -1085,11 +1224,25 @@ inline std::monostate Snapshot_t::resume_execution(SymEnv_t &sym_env, { auto timer = ManagedTimer(TimeProfileKind::RESUME_SNAPSHOT); // Restore the concrete states from the symbolic states - resume_conc_states(stack, frames, memory, Stack, Frames, Memory, sym_env); + resume_conc_states(stack, frames, memory, Stack, Frames, Memory, SymEnv); + } + int sym_size = 0; + { + auto timer = ManagedTimer(TimeProfileKind::COUNT_SYM_SIZE); + for (size_t i = 0; i < stack.size(); ++i) { + sym_size += stack[i].size(); + } + for (size_t i = 0; i < frames.size(); ++i) { + sym_size += frames[i].size(); + } } + std::cout << "[Info] Resumed symbolic execution from snapshot, total " + "symbolic expression and frame size: " + << sym_size << std::endl; + // Resume execution from the continuation auto timer = ManagedTimer(TimeProfileKind::INSTR); return cont(mcont); } -#endif // WASM_SYMBOLIC_RT_HPP \ No newline at end of file +#endif // WASM_SYMBOLIC_RT_HPP diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 739a0f39..cafddbf0 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -136,14 +136,20 @@ trait StagedWasmEvaluator extends SAIOps { }) } + trait Control - // TODO: maybe we don't need concern snapshot at compile time at all - trait Snapshot - - // Create a snapshot of the symbolic execution, we should ensure that current symstack is in use + // Save the current control information into a structure Control // We need to store the control information, so we can resume the execution later - def makeSnapshot(kont: Rep[Cont[Unit]], mkont: Rep[MCont[Unit]]): Rep[Snapshot] = { - "snapshot-make".reflectCtrlWith[Snapshot](kont, mkont) + def makeControl(kont: Rep[Cont[Unit]], mkont: Rep[MCont[Unit]]): Rep[Control] = { + "control-make".reflectCtrlWith[Control](kont, mkont) + } + + var instrCost: Int = 0 + + def addInstrCost(): Rep[Unit] = { + "add-instr-cost".reflectCtrlWith[Unit](instrCost) + instrCost = 0 + () } def eval(insts: List[Instr], @@ -152,7 +158,7 @@ trait StagedWasmEvaluator extends SAIOps { trail: Trail[Unit]) (implicit ctx: Context): Rep[Unit] = { if (insts.isEmpty) return kont(ctx)(mkont) - + instrCost += 1 // Predef.println(s"[DEBUG] Evaluating instructions: ${insts.mkString(", ")}") // Predef.println(s"[DEBUG] Current context: $ctx") @@ -352,19 +358,21 @@ trait StagedWasmEvaluator extends SAIOps { eval(els, restK _, mk, restK _ :: trail)(newCtx) }) if (cond.toInt != 0) { - val snapshot = makeSnapshot(elsK, mkont) - ExploreTree.moveCursor(true, snapshot) + val control = makeControl(elsK, mkont) + ExploreTree.moveCursor(true, control) thnK(mkont) } else { - val snapshot = makeSnapshot(thnK, mkont) - ExploreTree.moveCursor(false, snapshot) + val control = makeControl(thnK, mkont) + ExploreTree.moveCursor(false, control) elsK(mkont) } () case Br(label) => info(s"Jump to $label") + addInstrCost() trail(label)(ctx)(mkont) case BrIf(label) => + addInstrCost() val (ty, newCtx) = ctx.pop() val cond = Stack.popC(ty) val symCond = Stack.popS(ty) @@ -379,17 +387,18 @@ trait StagedWasmEvaluator extends SAIOps { }) if (cond.toInt != 0) { info(s"Jump to $label") - val snapshot = makeSnapshot(elsK, mkont) - ExploreTree.moveCursor(true, snapshot) + val control = makeControl(elsK, mkont) + ExploreTree.moveCursor(true, control) thnK(mkont) } else { info(s"Continue") - val snapshot = makeSnapshot(thnK, mkont) - ExploreTree.moveCursor(false, snapshot) + val control = makeControl(thnK, mkont) + ExploreTree.moveCursor(false, control) elsK(mkont) } () case BrTable(labels, default) => + addInstrCost() val (ty, newCtx) = ctx.pop() def aux(choices: List[Int], idx: Int, mkont: Rep[MCont[Unit]]): Rep[Unit] = { if (choices.isEmpty) { @@ -417,13 +426,13 @@ trait StagedWasmEvaluator extends SAIOps { aux(choices.tail, idx + 1, mk) }) if (cond.toInt != 0) { - val snapshot = makeSnapshot(elsK, mkont) - ExploreTree.moveCursor(true, snapshot) + val control = makeControl(elsK, mkont) + ExploreTree.moveCursor(true, control) thnK(mkont) } else { - val snapshot = makeSnapshot(thnK, mkont) - ExploreTree.moveCursor(false, snapshot) + val control = makeControl(thnK, mkont) + ExploreTree.moveCursor(false, control) elsK(mkont) } } @@ -451,6 +460,8 @@ trait StagedWasmEvaluator extends SAIOps { module.funcs(funcIndex) match { case FuncDef(_, FuncBodyDef(ty, _, bodyLocals, body)) => val locals = bodyLocals ++ ty.inps + instrCost += locals.size * 2 - 1 + addInstrCost() val callee = if (compileCache.contains(funcIndex)) { compileCache(funcIndex) @@ -505,12 +516,14 @@ trait StagedWasmEvaluator extends SAIOps { case Import("console", "log", _) | Import("spectest", "print_i32", _) => //println(s"[DEBUG] current stack: $stack") + addInstrCost() val (ty, newCtx) = ctx.pop() val v = Stack.popC(ty) Stack.popS(ty) println(v.toInt) eval(rest, kont, mkont, trail)(newCtx) case Import("console", "assert", _) => + addInstrCost() val (ty, newCtx) = ctx.pop() val v = Stack.popC(ty) // TODO: We should also add s into exploration tree @@ -858,9 +871,9 @@ trait StagedWasmEvaluator extends SAIOps { "tree-fill-finished".reflectCtrlWith[Unit]() } - def moveCursor(branch: Boolean, snapshot: Rep[Snapshot]): Rep[Unit] = { + def moveCursor(branch: Boolean, control: Rep[Control]): Rep[Unit] = { // when moving cursor from to an unexplored node, we need to change the reuse state - "tree-move-cursor".reflectCtrlWith[Unit](branch, snapshot) + "tree-move-cursor".reflectCtrlWith[Unit](branch, control) } def print(): Rep[Unit] = { @@ -1388,8 +1401,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("Stack.pop()") case Node(_, "sym-stack-pop", _, _) => emit("SymStack.pop()") - case Node(_, "snapshot-make", List(k, mk), _) => - emit("makeSnapshot("); shallow(k); emit(", "); shallow(mk); emit(")") + case Node(_, "control-make", List(k, mk), _) => + emit("makeControl("); shallow(k); emit(", "); shallow(mk); emit(")") case Node(_, "frame-pop", List(i), _) => emit("Frames.popFrame("); shallow(i); emit(")") case Node(_, "sym-frame-pop", List(i), _) => @@ -1511,6 +1524,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b, snapshot), _) => emit("ExploreTree.moveCursor("); shallow(b); emit(", "); shallow(snapshot); emit(")") + case Node(_, "add-instr-cost", List(n), _) => + emit("CostManager.add_instr_cost("); shallow(n); emit(")") case Node(_, "tree-print", List(), _) => emit("ExploreTree.print()") case Node(_, "tree-dump-graphviz", List(f), _) => From a1501030b56be67d3329b0516b4500d1f7dc4de3 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 18 Oct 2025 20:59:19 +0800 Subject: [PATCH 53/82] a cost model to determin if we want to create snapshot --- benchmarks/wasm/compare_wasp/Makefile | 10 ++++-- headers/wasm/config.hpp | 6 ++++ headers/wasm/profile.hpp | 4 +++ headers/wasm/symbolic_rt.hpp | 46 ++++++++++++++------------- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/benchmarks/wasm/compare_wasp/Makefile b/benchmarks/wasm/compare_wasp/Makefile index c9cc74ae..1c3e58c6 100644 --- a/benchmarks/wasm/compare_wasp/Makefile +++ b/benchmarks/wasm/compare_wasp/Makefile @@ -1,12 +1,16 @@ .PHONY: all run clean -all: large-branch.wat.cpp.imm.noreuse.exe large-branch.wat.cpp.imm.exe +all: large-branch.wat.cpp.imm.noreuse.exe large-branch.wat.cpp.imm.exe large-branch.wat.cpp.imm.cost-model.exe large-branch.wat.cpp.imm.noreuse.exe: large-branch.wat.cpp - g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.noreuse.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 -DNO_REUSE + g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.noreuse.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 -DNO_REUSE -DENABLE_PROFILE_STEP large-branch.wat.cpp.imm.exe: large-branch.wat.cpp - g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 + g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 -DENABLE_PROFILE_STEP + +large-branch.wat.cpp.imm.cost-model.exe: large-branch.wat.cpp + g++ large-branch.wat.cpp -o large-branch.wat.cpp.imm.cost-model.exe -DUSE_IMM -I ../../../headers -lz3 -DENABLE_PROFILE_TIME -O3 -DUSE_COST_MODEL + run: all ./large-branch.wat.cpp.imm.noreuse.exe diff --git a/headers/wasm/config.hpp b/headers/wasm/config.hpp index a9c8d5a1..037c6263 100644 --- a/headers/wasm/config.hpp +++ b/headers/wasm/config.hpp @@ -55,4 +55,10 @@ static const bool INTERACTIVE_MODE = true; static const bool INTERACTIVE_MODE = false; #endif +#ifdef USE_COST_MODEL +static const bool ENABLE_COST_MODEL = true; +#else +static const bool ENABLE_COST_MODEL = false; +#endif + #endif // CONFIG_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index bc4ce911..9814b5eb 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -20,6 +20,7 @@ enum class StepProfileKind { CURSOR_MOVE, MEM_GROW, SNAPSHOT_CREATE, + SYM_EVAL, OperationCount // keep this as the last element, this is used to get the // number of kinds of operations }; @@ -87,6 +88,9 @@ class Profile_t { << op_count[static_cast( StepProfileKind::SNAPSHOT_CREATE)] << std::endl; + std::cout << "Total SYM_EVAL operations: " + << op_count[static_cast(StepProfileKind::SYM_EVAL)] + << std::endl; std::cout << "Total time for instruction execution (s): " << std::setprecision(15) << execution_time << std::endl; } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 1423dcf1..6edef6ee 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -855,7 +855,8 @@ inline int Snapshot_t::cost_of_snapshot() { auto cost_of_stack_copy = SymStack.cost_of_copy(); auto cost_of_frame_copy = SymFrames.cost_of_copy(); auto cost_of_memory_copy = SymMemory.cost_of_copy(); - return cost_of_stack_copy + cost_of_frame_copy + cost_of_memory_copy; + return 5.336 * + (cost_of_stack_copy + cost_of_frame_copy + cost_of_memory_copy); } class ExploreTree_t { public: @@ -896,19 +897,23 @@ class ExploreTree_t { } bool worth_to_create_snapshot() { + if (!ENABLE_COST_MODEL) { + return REUSE_SNAPSHOT; + } // find out the best way to reach the current position via our cost model auto snapshot_cost = Snapshot_t::cost_of_snapshot(); - auto parent_cost = - cursor->parent ? cursor->parent->min_cost_of_reaching_here() : 0; - auto exec_from_parent_cost = - cursor->min_cost_of_reaching_here() + cursor->instr_cost; - // TODO: return a random result to test the infrastructure, replace this to the - // real cost model later - if (std::rand() % 2 == 0) { - return true; + int reach_parent_cost = 0; + if (cursor->parent) { + reach_parent_cost = cursor->parent->min_cost_of_reaching_here(); } else { - return false; + reach_parent_cost = 0; } + auto parent_cost = + cursor->parent ? cursor->parent->min_cost_of_reaching_here() : 0; + auto exec_from_parent_cost = reach_parent_cost + cursor->instr_cost; + GENSYM_INFO("The score of snapshot tendency: " + std::to_string(exec_from_parent_cost - + snapshot_cost)); + return snapshot_cost <= exec_from_parent_cost; } std::monostate moveCursor(bool branch, Control control) { @@ -921,22 +926,18 @@ class ExploreTree_t { int cost_from_parent = CostManager.dump_instr_cost(); if (branch) { true_branch_cov_map[if_else_node->id] = true; - if (REUSE_SNAPSHOT) { - if (worth_to_create_snapshot()) { - auto snapshot = makeSnapshot(control); - if_else_node->false_branch->fillSnapshotNode(snapshot); - } + if (worth_to_create_snapshot()) { + auto snapshot = makeSnapshot(control); + if_else_node->false_branch->fillSnapshotNode(snapshot); } else { // Do nothing, the initial value of the branch is an unexplored node } cursor = if_else_node->true_branch.get(); } else { false_branch_cov_map[if_else_node->id] = true; - if (REUSE_SNAPSHOT) { - if (worth_to_create_snapshot()) { - auto snapshot = makeSnapshot(control); - if_else_node->true_branch->fillSnapshotNode(snapshot); - } + if (worth_to_create_snapshot()) { + auto snapshot = makeSnapshot(control); + if_else_node->true_branch->fillSnapshotNode(snapshot); } else { // Do nothing, the initial value of the branch is an unexplored node } @@ -1077,8 +1078,8 @@ inline void NodeBox::reach_here(std::function entrypoint) { assert(REUSE_SNAPSHOT); auto snap = snapshot->get_snapshot(); snap.resume_execution(this); - } - if (parent == nullptr) { + return; + } else if (parent == nullptr) { // if it's the root node, the only way to reach here is to reset everything // and start a new execution assert(this == ExploreTree.get_root() && @@ -1104,6 +1105,7 @@ struct EvalRes { // TODO: reduce the re-computation of the same symbolic expression, it's better // if it can be done by the smt solver static EvalRes eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { + Profile.step(StepProfileKind::SYM_EVAL); assert(sym.symptr != nullptr && "Symbolic expression is null"); if (auto concrete = dynamic_cast(sym.symptr.get())) { return EvalRes(concrete->value, 32); From 2ad0949337f8c8c2fcd3e9e96da50c9700854680 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 20:31:18 -0400 Subject: [PATCH 54/82] update btree benchmarks --- benchmarks/pldi2026/btree/2o1u.wast | 3655 +++++++++++++++ benchmarks/pldi2026/btree/2o2u.wast | 3694 +++++++++++++++ benchmarks/pldi2026/btree/2o3u.wast | 3740 +++++++++++++++ benchmarks/pldi2026/btree/3o1u.wast | 3698 +++++++++++++++ benchmarks/pldi2026/btree/3o2u.wast | 3744 +++++++++++++++ benchmarks/pldi2026/btree/3o3u.wast | 3795 +++++++++++++++ benchmarks/pldi2026/btree/4o1u.wast | 3747 +++++++++++++++ benchmarks/pldi2026/btree/4o2u.wast | 3798 +++++++++++++++ benchmarks/pldi2026/btree/4o3u.wast | 3854 +++++++++++++++ benchmarks/pldi2026/btree/5o1u.wast | 3801 +++++++++++++++ benchmarks/pldi2026/btree/5o2u.wast | 3858 +++++++++++++++ benchmarks/pldi2026/btree/5o3u.wast | 3915 ++++++++++++++++ benchmarks/pldi2026/btree/6o1u.wast | 3861 +++++++++++++++ benchmarks/pldi2026/btree/6o2u.wast | 3922 ++++++++++++++++ benchmarks/pldi2026/btree/6o3u.wast | 3987 ++++++++++++++++ benchmarks/pldi2026/btree/7o1u.wast | 3926 ++++++++++++++++ benchmarks/pldi2026/btree/7o2u.wast | 3992 ++++++++++++++++ benchmarks/pldi2026/btree/7o3u.wast | 4065 ++++++++++++++++ benchmarks/pldi2026/btree/8o1u.wast | 3996 ++++++++++++++++ benchmarks/pldi2026/btree/8o2u.wast | 4059 ++++++++++++++++ benchmarks/pldi2026/btree/9o1u.wast | 4072 ++++++++++++++++ benchmarks/pldi2026/btree/9o2u.wast | 4147 +++++++++++++++++ .../wasm/btree/2o1u-unlabeled.wat copy.cpp | 71 + benchmarks/wasm/btree/Makefile | 53 + 24 files changed, 85450 insertions(+) create mode 100644 benchmarks/pldi2026/btree/2o1u.wast create mode 100644 benchmarks/pldi2026/btree/2o2u.wast create mode 100644 benchmarks/pldi2026/btree/2o3u.wast create mode 100644 benchmarks/pldi2026/btree/3o1u.wast create mode 100644 benchmarks/pldi2026/btree/3o2u.wast create mode 100644 benchmarks/pldi2026/btree/3o3u.wast create mode 100644 benchmarks/pldi2026/btree/4o1u.wast create mode 100644 benchmarks/pldi2026/btree/4o2u.wast create mode 100644 benchmarks/pldi2026/btree/4o3u.wast create mode 100644 benchmarks/pldi2026/btree/5o1u.wast create mode 100644 benchmarks/pldi2026/btree/5o2u.wast create mode 100644 benchmarks/pldi2026/btree/5o3u.wast create mode 100644 benchmarks/pldi2026/btree/6o1u.wast create mode 100644 benchmarks/pldi2026/btree/6o2u.wast create mode 100644 benchmarks/pldi2026/btree/6o3u.wast create mode 100644 benchmarks/pldi2026/btree/7o1u.wast create mode 100644 benchmarks/pldi2026/btree/7o2u.wast create mode 100644 benchmarks/pldi2026/btree/7o3u.wast create mode 100644 benchmarks/pldi2026/btree/8o1u.wast create mode 100644 benchmarks/pldi2026/btree/8o2u.wast create mode 100644 benchmarks/pldi2026/btree/9o1u.wast create mode 100644 benchmarks/pldi2026/btree/9o2u.wast create mode 100644 benchmarks/wasm/btree/2o1u-unlabeled.wat copy.cpp create mode 100644 benchmarks/wasm/btree/Makefile diff --git a/benchmarks/pldi2026/btree/2o1u.wast b/benchmarks/pldi2026/btree/2o1u.wast new file mode 100644 index 00000000..b9384f56 --- /dev/null +++ b/benchmarks/pldi2026/btree/2o1u.wast @@ -0,0 +1,3655 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 2 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;; logical order: a>b + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (i32.and) + + ;; 1 symbolic variable w/o order + ;; h + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (print_stack) + (i32.const -1) + (i32.eq) + (print_stack) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (print_stack) + (i32.const -1) + (i32.eq) + (print_stack) + + + (print_btree) + + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00h\00")) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/2o2u.wast b/benchmarks/pldi2026/btree/2o2u.wast new file mode 100644 index 00000000..384e4fee --- /dev/null +++ b/benchmarks/pldi2026/btree/2o2u.wast @@ -0,0 +1,3694 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 2 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;; logical order: a>b + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + ;; i + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00h\00i\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/2o3u.wast b/benchmarks/pldi2026/btree/2o3u.wast new file mode 100644 index 00000000..090f36e0 --- /dev/null +++ b/benchmarks/pldi2026/btree/2o3u.wast @@ -0,0 +1,3740 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 2 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;; logical order: a>b + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1028) + (i32.symbolic) + (sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + ;; i + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + ;; j + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/3o1u.wast b/benchmarks/pldi2026/btree/3o1u.wast new file mode 100644 index 00000000..ef2c9309 --- /dev/null +++ b/benchmarks/pldi2026/btree/3o1u.wast @@ -0,0 +1,3698 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 3 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;; logical order: a>b>c + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variable w/o order + ;; h + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/3o2u.wast b/benchmarks/pldi2026/btree/3o2u.wast new file mode 100644 index 00000000..ffa990f1 --- /dev/null +++ b/benchmarks/pldi2026/btree/3o2u.wast @@ -0,0 +1,3744 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 3 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;; logical order: a>b>c + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + ;; i + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/3o3u.wast b/benchmarks/pldi2026/btree/3o3u.wast new file mode 100644 index 00000000..0c191307 --- /dev/null +++ b/benchmarks/pldi2026/btree/3o3u.wast @@ -0,0 +1,3795 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 3 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + + ;; logical order: a>b>c + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 3 symbolic variables w/o order + ;; h + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + ;; i + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + ;; j + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/4o1u.wast b/benchmarks/pldi2026/btree/4o1u.wast new file mode 100644 index 00000000..da420339 --- /dev/null +++ b/benchmarks/pldi2026/btree/4o1u.wast @@ -0,0 +1,3747 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 4 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;; logical order: a>b>c>d + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variables w/o order + ;; h + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/4o2u.wast b/benchmarks/pldi2026/btree/4o2u.wast new file mode 100644 index 00000000..7b3c6eec --- /dev/null +++ b/benchmarks/pldi2026/btree/4o2u.wast @@ -0,0 +1,3798 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 4 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;; logical order: a>b>c>d + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + ;; i + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/4o3u.wast b/benchmarks/pldi2026/btree/4o3u.wast new file mode 100644 index 00000000..30faaedd --- /dev/null +++ b/benchmarks/pldi2026/btree/4o3u.wast @@ -0,0 +1,3854 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 4 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;; logical order: a>b>c>d + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + ;; i + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + ;; j + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/5o1u.wast b/benchmarks/pldi2026/btree/5o1u.wast new file mode 100644 index 00000000..9c633870 --- /dev/null +++ b/benchmarks/pldi2026/btree/5o1u.wast @@ -0,0 +1,3801 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; logical order: a>b>c>d>e + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variable w/o order + ;; h + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/5o2u.wast b/benchmarks/pldi2026/btree/5o2u.wast new file mode 100644 index 00000000..cb2a650f --- /dev/null +++ b/benchmarks/pldi2026/btree/5o2u.wast @@ -0,0 +1,3858 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; logical order: a>b>c>d>e + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variable w/o order + ;; h + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + ;; i + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/5o3u.wast b/benchmarks/pldi2026/btree/5o3u.wast new file mode 100644 index 00000000..6342b1a5 --- /dev/null +++ b/benchmarks/pldi2026/btree/5o3u.wast @@ -0,0 +1,3915 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; logical order: a>b>c>d>e + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 3 symbolic variable w/o order + ;; h + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + ;; i + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + ;; j + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/6o1u.wast b/benchmarks/pldi2026/btree/6o1u.wast new file mode 100644 index 00000000..ccc8520f --- /dev/null +++ b/benchmarks/pldi2026/btree/6o1u.wast @@ -0,0 +1,3861 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 6 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + + ;; logical order: a>b>c>d>e>f + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + + ;; 1 symbolic variables w/o order + ;; h + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/6o2u.wast b/benchmarks/pldi2026/btree/6o2u.wast new file mode 100644 index 00000000..9038d51e --- /dev/null +++ b/benchmarks/pldi2026/btree/6o2u.wast @@ -0,0 +1,3922 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 6 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + + ;; logical order: a>b>c>d>e>f + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + ;; i + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/6o3u.wast b/benchmarks/pldi2026/btree/6o3u.wast new file mode 100644 index 00000000..153c95b7 --- /dev/null +++ b/benchmarks/pldi2026/btree/6o3u.wast @@ -0,0 +1,3987 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 6 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + + ;; logical order: a>b>c>d>e>f + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + + ;; 3 symbolic variables w/o order + ;; h + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + ;; i + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + ;; i + (i32.const 1040) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/7o1u.wast b/benchmarks/pldi2026/btree/7o1u.wast new file mode 100644 index 00000000..69e17d05 --- /dev/null +++ b/benchmarks/pldi2026/btree/7o1u.wast @@ -0,0 +1,3926 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/7o2u.wast b/benchmarks/pldi2026/btree/7o2u.wast new file mode 100644 index 00000000..7c5b411a --- /dev/null +++ b/benchmarks/pldi2026/btree/7o2u.wast @@ -0,0 +1,3992 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + + ;; i + (i32.const 1040) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/7o3u.wast b/benchmarks/pldi2026/btree/7o3u.wast new file mode 100644 index 00000000..c51d9b64 --- /dev/null +++ b/benchmarks/pldi2026/btree/7o3u.wast @@ -0,0 +1,4065 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 3 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + + ;; i + (i32.const 1040) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + ;; i + (i32.const 1042) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/8o1u.wast b/benchmarks/pldi2026/btree/8o1u.wast new file mode 100644 index 00000000..3c942501 --- /dev/null +++ b/benchmarks/pldi2026/btree/8o1u.wast @@ -0,0 +1,3996 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; x + (i32.const 1044) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "g") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g>x + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + (get_sym_int32 "g") + (get_sym_int32 "x") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "x") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "x") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; x + (local.get 0) + (get_sym_int32 "x") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/8o2u.wast b/benchmarks/pldi2026/btree/8o2u.wast new file mode 100644 index 00000000..9d19d9f7 --- /dev/null +++ b/benchmarks/pldi2026/btree/8o2u.wast @@ -0,0 +1,4059 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (sym_int32 "a") + (sym_int32 "b") + (i32.ne) + + ;;c + (sym_int32 "c") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (sym_int32 "d") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (sym_int32 "e") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (sym_int32 "f") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (sym_int32 "g") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; x + (sym_int32 "x") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "g") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g>x + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + (get_sym_int32 "g") + (get_sym_int32 "x") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (sym_int32 "h") + (sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "x") + (i32.ne) + + ;; i + (sym_int32 "i") + (sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "x") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "x") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; x + (local.get 0) + (get_sym_int32 "x") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/9o1u.wast b/benchmarks/pldi2026/btree/9o1u.wast new file mode 100644 index 00000000..ef8a9448 --- /dev/null +++ b/benchmarks/pldi2026/btree/9o1u.wast @@ -0,0 +1,4072 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; x + (i32.const 1044) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "g") + (i32.ne) + + ;; y + (i32.const 1046) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "x") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g>x>y + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + (get_sym_int32 "g") + (get_sym_int32 "x") + (i32.gt_s) + + (get_sym_int32 "x") + (get_sym_int32 "y") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 1 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "x") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "y") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "x") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "y") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "y") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; x + (local.get 0) + (get_sym_int32 "x") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; y + (local.get 0) + (get_sym_int32 "y") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "y") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") +) +(invoke "main") diff --git a/benchmarks/pldi2026/btree/9o2u.wast b/benchmarks/pldi2026/btree/9o2u.wast new file mode 100644 index 00000000..88a7615a --- /dev/null +++ b/benchmarks/pldi2026/btree/9o2u.wast @@ -0,0 +1,4147 @@ +(module + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 9 symbolic variables w/ order + ;; a and b + (i32.const 1024) + (i32.symbolic) + (i32.const 1026) + (i32.symbolic) + (i32.ne) + + ;;c + (i32.const 1028) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne) + + ;;d + (i32.const 1030) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne) + + ;;e + (i32.const 1032) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne) + + ;; f + (i32.const 1034) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (i32.const 1036) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; x + (i32.const 1044) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "x") + (get_sym_int32 "g") + (i32.ne) + + ;; y + (i32.const 1046) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "y") + (get_sym_int32 "x") + (i32.ne) + + ;; logical order: a>b>c>d>e>f>g>x>y + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s) + + (get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s) + + (get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s) + + (get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + (get_sym_int32 "g") + (get_sym_int32 "x") + (i32.gt_s) + + (get_sym_int32 "x") + (get_sym_int32 "y") + (i32.gt_s) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (i32.const 1038) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "x") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "y") + (i32.ne) + + ;; i + (i32.const 1040) + (i32.symbolic) + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "x") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "y") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "c") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "d") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "e") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "x") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "y") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "y") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; e + (local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; x + (local.get 0) + (get_sym_int32 "x") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "x") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; y + (local.get 0) + (get_sym_int32 "y") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "y") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + ) + (export "main" (func $main)) + (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") +) +(invoke "main") diff --git a/benchmarks/wasm/btree/2o1u-unlabeled.wat copy.cpp b/benchmarks/wasm/btree/2o1u-unlabeled.wat copy.cpp new file mode 100644 index 00000000..a449fd2a --- /dev/null +++ b/benchmarks/wasm/btree/2o1u-unlabeled.wat copy.cpp @@ -0,0 +1,71 @@ +std::monostate Snippet(std::monostate x0) { +Globals.pushFrame(0); +SymGlobals.pushFrame(0); +Frames.pushFrame(0); +SymFrames.pushFrame(0); +Stack.push(I32V(2)); +SymStack.push(Concrete(I32V(2))); +Stack.pop(); +SymVal x3 = SymStack.pop(); +SymVal x4 = x3.makeSymbolic(); +Stack.push(SymEnv.read(x4)); +SymStack.push(x4); +Stack.push(I32V(1)); +SymStack.push(Concrete(I32V(1))); +Stack.pop(); +SymVal x5 = SymStack.pop(); +SymVal x6 = x5.makeSymbolic(); +Stack.push(SymEnv.read(x6)); +SymStack.push(x6); +Stack.push(I32V(0)); +SymStack.push(Concrete(I32V(0))); +Stack.pop(); +SymVal x7 = SymStack.pop(); +SymVal x8 = x7.makeSymbolic(); +Stack.push(SymEnv.read(x8)); +SymStack.push(x8); +CostManager.add_instr_cost(14); +info("Exiting the function at 5, stackSize =", Stack.size()); +Frames.popFrame(6); +SymFrames.popFrame(6); +Num x5014 = Stack.peek(); +SymVal x5015 = SymStack.peek(); +Frames.set(3, x5014); +SymFrames.set(3, x5015); +Stack.push(Frames.get(1)); +SymStack.push(SymFrames.get(1)); +CostManager.add_instr_cost(8); +Stack.pop(); +Stack.pop(); +SymStack.pop(); +SymStack.pop(); +std::monostate x5032 = std::monostate(); +std::function x5033; +x5033 = [=](std::monostate x5034)->std::monostate { +std::monostate(); +return x5018(x5035); +}; +Num x5180 = Stack.pop(); +Num x5181 = Stack.pop(); +Num x5182 = Stack.pop(); +SymVal x5183 = SymStack.pop(); +SymVal x5184 = SymStack.pop(); +SymVal x5185 = SymStack.pop(); +std::monostate x5190 = std::monostate(); +std::function x5191; +x5191 = [=](std::monostate x5192)->std::monostate { +std::monostate(); +return x5188(x1); +}; +Frames.pushFrame(4); +SymFrames.pushFrame(4); +Frames.set(0, x5182); +Frames.set(1, x5181); +Frames.set(2, x5180); +SymFrames.set(0, x5185); +SymFrames.set(1, x5184); +SymFrames.set(2, x5183); +x5153(x5191); +Frames.popFrame(0); +return SymFrames.popFrame(0); +} \ No newline at end of file diff --git a/benchmarks/wasm/btree/Makefile b/benchmarks/wasm/btree/Makefile new file mode 100644 index 00000000..a876c01d --- /dev/null +++ b/benchmarks/wasm/btree/Makefile @@ -0,0 +1,53 @@ +# Makefile for building different versions of 2o1u-unlabeled.wat.cpp + +CXX := g++ +SRC := 2o1u-unlabeled.wat.cpp +HEADERS := ../../headers/ +LDFLAGS := -lz3 +CXXFLAGS := -g -I $(HEADERS) -std=c++17 -DENABLE_PROFILE -fno-omit-frame-pointer -O3 -DENABLE_PROFILE_TIME + +.PHONY: all clean benchmark + +all: 2o1u-unlabeled.wat.cpp.imm.no-snap.exe 2o1u-unlabeled.wat.cpp.imm.exe 2o1u-unlabeled.wat.cpp.no-snap.exe 2o1u-unlabeled.wat.cpp.exe \ + 2o1u-unlabeled.wat.cpp.concolic.imm.no-snap.exe 2o1u-unlabeled.wat.cpp.concolic.imm.exe 2o1u-unlabeled.wat.cpp.concolic.no-snap.exe 2o1u-unlabeled.wat.cpp.concolic.exe 2o1u-unlabeled.wat.cpp.concolic.imm.cost-model.exe + +2o1u-unlabeled.wat.cpp.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DRUN_ONCE + +2o1u-unlabeled.wat.cpp.no-snap.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DNO_REUSE -DRUN_ONCE + +2o1u-unlabeled.wat.cpp.imm.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DUSE_IMM -DRUN_ONCE + +2o1u-unlabeled.wat.cpp.imm.no-snap.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DUSE_IMM -DNO_REUSE -DRUN_ONCE + + +## Concolic execution tests +2o1u-unlabeled.wat.cpp.concolic.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DBY_COVERAGE + +2o1u-unlabeled.wat.cpp.concolic.no-snap.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DNO_REUSE -DBY_COVERAGE + +2o1u-unlabeled.wat.cpp.concolic.imm.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DUSE_IMM -DBY_COVERAGE + +2o1u-unlabeled.wat.cpp.concolic.imm.no-snap.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DUSE_IMM -DNO_REUSE -DBY_COVERAGE + +2o1u-unlabeled.wat.cpp.concolic.imm.cost-model.exe: $(SRC) + $(CXX) $< -o $@ $(CXXFLAGS) $(LDFLAGS) -DUSE_IMM -DNO_REUSE -DBY_COVERAGE -DUSE_COST_MODEL + +benchmark: all + hyperfine './2o1u-unlabeled.wat.cpp.imm.no-snap.exe' \ + './2o1u-unlabeled.wat.cpp.imm.exe' \ + './2o1u-unlabeled.wat.cpp.no-snap.exe' \ + './2o1u-unlabeled.wat.cpp.exe' + hyperfine './2o1u-unlabeled.wat.cpp.concolic.imm.no-snap.exe' \ + './2o1u-unlabeled.wat.cpp.concolic.imm.exe' \ + './2o1u-unlabeled.wat.cpp.concolic.no-snap.exe' \ + './2o1u-unlabeled.wat.cpp.concolic.exe' +clean: + rm -f *.exe From a3ad84f32595a3d1d438de93e01cbbe38dc6232b Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:10:40 -0400 Subject: [PATCH 55/82] rename --- .../pldi2026/btree/{2o1u.wast => 2o1u.wat} | 80 ++++++++++++------- .../pldi2026/btree/{2o2u.wast => 2o2u.wat} | 0 .../pldi2026/btree/{2o3u.wast => 2o3u.wat} | 0 .../pldi2026/btree/{3o1u.wast => 3o1u.wat} | 0 .../pldi2026/btree/{3o2u.wast => 3o2u.wat} | 0 .../pldi2026/btree/{3o3u.wast => 3o3u.wat} | 0 .../pldi2026/btree/{4o1u.wast => 4o1u.wat} | 0 .../pldi2026/btree/{4o2u.wast => 4o2u.wat} | 0 .../pldi2026/btree/{4o3u.wast => 4o3u.wat} | 0 .../pldi2026/btree/{5o1u.wast => 5o1u.wat} | 0 .../pldi2026/btree/{5o2u.wast => 5o2u.wat} | 0 .../pldi2026/btree/{5o3u.wast => 5o3u.wat} | 0 .../pldi2026/btree/{6o1u.wast => 6o1u.wat} | 0 .../pldi2026/btree/{6o2u.wast => 6o2u.wat} | 0 .../pldi2026/btree/{6o3u.wast => 6o3u.wat} | 0 .../pldi2026/btree/{7o1u.wast => 7o1u.wat} | 0 .../pldi2026/btree/{7o2u.wast => 7o2u.wat} | 0 .../pldi2026/btree/{7o3u.wast => 7o3u.wat} | 0 .../pldi2026/btree/{8o1u.wast => 8o1u.wat} | 0 .../pldi2026/btree/{8o2u.wast => 8o2u.wat} | 0 .../pldi2026/btree/{9o1u.wast => 9o1u.wat} | 0 .../pldi2026/btree/{9o2u.wast => 9o2u.wat} | 0 22 files changed, 51 insertions(+), 29 deletions(-) rename benchmarks/pldi2026/btree/{2o1u.wast => 2o1u.wat} (98%) rename benchmarks/pldi2026/btree/{2o2u.wast => 2o2u.wat} (100%) rename benchmarks/pldi2026/btree/{2o3u.wast => 2o3u.wat} (100%) rename benchmarks/pldi2026/btree/{3o1u.wast => 3o1u.wat} (100%) rename benchmarks/pldi2026/btree/{3o2u.wast => 3o2u.wat} (100%) rename benchmarks/pldi2026/btree/{3o3u.wast => 3o3u.wat} (100%) rename benchmarks/pldi2026/btree/{4o1u.wast => 4o1u.wat} (100%) rename benchmarks/pldi2026/btree/{4o2u.wast => 4o2u.wat} (100%) rename benchmarks/pldi2026/btree/{4o3u.wast => 4o3u.wat} (100%) rename benchmarks/pldi2026/btree/{5o1u.wast => 5o1u.wat} (100%) rename benchmarks/pldi2026/btree/{5o2u.wast => 5o2u.wat} (100%) rename benchmarks/pldi2026/btree/{5o3u.wast => 5o3u.wat} (100%) rename benchmarks/pldi2026/btree/{6o1u.wast => 6o1u.wat} (100%) rename benchmarks/pldi2026/btree/{6o2u.wast => 6o2u.wat} (100%) rename benchmarks/pldi2026/btree/{6o3u.wast => 6o3u.wat} (100%) rename benchmarks/pldi2026/btree/{7o1u.wast => 7o1u.wat} (100%) rename benchmarks/pldi2026/btree/{7o2u.wast => 7o2u.wat} (100%) rename benchmarks/pldi2026/btree/{7o3u.wast => 7o3u.wat} (100%) rename benchmarks/pldi2026/btree/{8o1u.wast => 8o1u.wat} (100%) rename benchmarks/pldi2026/btree/{8o2u.wast => 8o2u.wat} (100%) rename benchmarks/pldi2026/btree/{9o1u.wast => 9o1u.wat} (100%) rename benchmarks/pldi2026/btree/{9o2u.wast => 9o2u.wat} (100%) diff --git a/benchmarks/pldi2026/btree/2o1u.wast b/benchmarks/pldi2026/btree/2o1u.wat similarity index 98% rename from benchmarks/pldi2026/btree/2o1u.wast rename to benchmarks/pldi2026/btree/2o1u.wat index b9384f56..d57fe9d2 100644 --- a/benchmarks/pldi2026/btree/2o1u.wast +++ b/benchmarks/pldi2026/btree/2o1u.wat @@ -1,7 +1,15 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) + (memory $0 1) - + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree (i32.const 0) (local.get 0) @@ -3548,14 +3556,16 @@ ;; 2 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) - (i32.ne) + (call $i32.symbolic) + (i32.ne) ;; logical order: a>b - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) (i32.and) @@ -3563,46 +3573,55 @@ ;; 1 symbolic variable w/o order ;; h (i32.const 1028) - (i32.symbolic) - (get_sym_int32 "a") + (call $i32.symbolic) + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3613,43 +3632,46 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) - (print_stack) + ;; (print_stack) (i32.const -1) (i32.eq) - (print_stack) + ;; (print_stack) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) - (print_stack) + ;; (print_stack) (i32.const -1) (i32.eq) - (print_stack) + ;; (print_stack) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00h\00")) -(invoke "main") diff --git a/benchmarks/pldi2026/btree/2o2u.wast b/benchmarks/pldi2026/btree/2o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/2o2u.wast rename to benchmarks/pldi2026/btree/2o2u.wat diff --git a/benchmarks/pldi2026/btree/2o3u.wast b/benchmarks/pldi2026/btree/2o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/2o3u.wast rename to benchmarks/pldi2026/btree/2o3u.wat diff --git a/benchmarks/pldi2026/btree/3o1u.wast b/benchmarks/pldi2026/btree/3o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/3o1u.wast rename to benchmarks/pldi2026/btree/3o1u.wat diff --git a/benchmarks/pldi2026/btree/3o2u.wast b/benchmarks/pldi2026/btree/3o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/3o2u.wast rename to benchmarks/pldi2026/btree/3o2u.wat diff --git a/benchmarks/pldi2026/btree/3o3u.wast b/benchmarks/pldi2026/btree/3o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/3o3u.wast rename to benchmarks/pldi2026/btree/3o3u.wat diff --git a/benchmarks/pldi2026/btree/4o1u.wast b/benchmarks/pldi2026/btree/4o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/4o1u.wast rename to benchmarks/pldi2026/btree/4o1u.wat diff --git a/benchmarks/pldi2026/btree/4o2u.wast b/benchmarks/pldi2026/btree/4o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/4o2u.wast rename to benchmarks/pldi2026/btree/4o2u.wat diff --git a/benchmarks/pldi2026/btree/4o3u.wast b/benchmarks/pldi2026/btree/4o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/4o3u.wast rename to benchmarks/pldi2026/btree/4o3u.wat diff --git a/benchmarks/pldi2026/btree/5o1u.wast b/benchmarks/pldi2026/btree/5o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/5o1u.wast rename to benchmarks/pldi2026/btree/5o1u.wat diff --git a/benchmarks/pldi2026/btree/5o2u.wast b/benchmarks/pldi2026/btree/5o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/5o2u.wast rename to benchmarks/pldi2026/btree/5o2u.wat diff --git a/benchmarks/pldi2026/btree/5o3u.wast b/benchmarks/pldi2026/btree/5o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/5o3u.wast rename to benchmarks/pldi2026/btree/5o3u.wat diff --git a/benchmarks/pldi2026/btree/6o1u.wast b/benchmarks/pldi2026/btree/6o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/6o1u.wast rename to benchmarks/pldi2026/btree/6o1u.wat diff --git a/benchmarks/pldi2026/btree/6o2u.wast b/benchmarks/pldi2026/btree/6o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/6o2u.wast rename to benchmarks/pldi2026/btree/6o2u.wat diff --git a/benchmarks/pldi2026/btree/6o3u.wast b/benchmarks/pldi2026/btree/6o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/6o3u.wast rename to benchmarks/pldi2026/btree/6o3u.wat diff --git a/benchmarks/pldi2026/btree/7o1u.wast b/benchmarks/pldi2026/btree/7o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/7o1u.wast rename to benchmarks/pldi2026/btree/7o1u.wat diff --git a/benchmarks/pldi2026/btree/7o2u.wast b/benchmarks/pldi2026/btree/7o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/7o2u.wast rename to benchmarks/pldi2026/btree/7o2u.wat diff --git a/benchmarks/pldi2026/btree/7o3u.wast b/benchmarks/pldi2026/btree/7o3u.wat similarity index 100% rename from benchmarks/pldi2026/btree/7o3u.wast rename to benchmarks/pldi2026/btree/7o3u.wat diff --git a/benchmarks/pldi2026/btree/8o1u.wast b/benchmarks/pldi2026/btree/8o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/8o1u.wast rename to benchmarks/pldi2026/btree/8o1u.wat diff --git a/benchmarks/pldi2026/btree/8o2u.wast b/benchmarks/pldi2026/btree/8o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/8o2u.wast rename to benchmarks/pldi2026/btree/8o2u.wat diff --git a/benchmarks/pldi2026/btree/9o1u.wast b/benchmarks/pldi2026/btree/9o1u.wat similarity index 100% rename from benchmarks/pldi2026/btree/9o1u.wast rename to benchmarks/pldi2026/btree/9o1u.wat diff --git a/benchmarks/pldi2026/btree/9o2u.wast b/benchmarks/pldi2026/btree/9o2u.wat similarity index 100% rename from benchmarks/pldi2026/btree/9o2u.wast rename to benchmarks/pldi2026/btree/9o2u.wat From 8a8d6d02d6699b23d88ed4f18fa1abc0b7e3a4cb Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:12:23 -0400 Subject: [PATCH 56/82] turn wast to wat --- benchmarks/pldi2026/btree/2o2u.wat | 2 +- benchmarks/pldi2026/btree/2o3u.wat | 2 +- benchmarks/pldi2026/btree/3o1u.wat | 2 +- benchmarks/pldi2026/btree/3o2u.wat | 2 +- benchmarks/pldi2026/btree/3o3u.wat | 2 +- benchmarks/pldi2026/btree/4o1u.wat | 2 +- benchmarks/pldi2026/btree/4o2u.wat | 2 +- benchmarks/pldi2026/btree/4o3u.wat | 2 +- benchmarks/pldi2026/btree/5o1u.wat | 2 +- benchmarks/pldi2026/btree/5o2u.wat | 2 +- benchmarks/pldi2026/btree/5o3u.wat | 2 +- benchmarks/pldi2026/btree/6o1u.wat | 2 +- benchmarks/pldi2026/btree/6o2u.wat | 2 +- benchmarks/pldi2026/btree/6o3u.wat | 2 +- benchmarks/pldi2026/btree/7o1u.wat | 2 +- benchmarks/pldi2026/btree/7o2u.wat | 2 +- benchmarks/pldi2026/btree/7o3u.wat | 2 +- benchmarks/pldi2026/btree/8o1u.wat | 2 +- benchmarks/pldi2026/btree/8o2u.wat | 2 +- benchmarks/pldi2026/btree/9o1u.wat | 2 +- benchmarks/pldi2026/btree/9o2u.wat | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 384e4fee..d5172a5e 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3691,4 +3691,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00h\00i\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index 090f36e0..2d0a90ae 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3737,4 +3737,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index ef2c9309..b9d56a09 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3695,4 +3695,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index ffa990f1..17824b8c 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3741,4 +3741,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 0c191307..01e18274 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3792,4 +3792,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index da420339..0a929b47 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3744,4 +3744,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 7b3c6eec..e7c20f49 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3795,4 +3795,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 30faaedd..8008797d 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3851,4 +3851,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 9c633870..44eb9448 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3798,4 +3798,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index cb2a650f..961fe3dd 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3855,4 +3855,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 6342b1a5..02a3a0e9 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3912,4 +3912,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index ccc8520f..8d609fba 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3858,4 +3858,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 9038d51e..33292ec4 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3919,4 +3919,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 153c95b7..24fe6fd1 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3984,4 +3984,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 69e17d05..bfa1a2b1 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3923,4 +3923,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 7c5b411a..1b9fee44 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3989,4 +3989,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index c51d9b64..783374a1 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -4062,4 +4062,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 3c942501..9fb9a51a 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3993,4 +3993,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index 9d19d9f7..be3cc6b6 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -4056,4 +4056,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index ef8a9448..73f3820f 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -4069,4 +4069,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") ) -(invoke "main") + diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 88a7615a..3ecf8dbf 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -4144,4 +4144,4 @@ (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") ) -(invoke "main") + From ea0510127a93fa0f8fa061ef21edb7e8d49a5d1c Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:16:30 -0400 Subject: [PATCH 57/82] use imported api for symbolic operations so they can be run by wat2wasm currently only 2o2u.wat works --- benchmarks/pldi2026/btree/2o2u.wat | 7 + benchmarks/pldi2026/btree/2o3u.wat | 7 + benchmarks/pldi2026/btree/3o1u.wat | 7 + benchmarks/pldi2026/btree/3o2u.wat | 7 + benchmarks/pldi2026/btree/3o3u.wat | 7 + benchmarks/pldi2026/btree/4o1u.wat | 7 + benchmarks/pldi2026/btree/4o2u.wat | 7 + benchmarks/pldi2026/btree/4o3u.wat | 7 + benchmarks/pldi2026/btree/5o1u.wat | 7 + benchmarks/pldi2026/btree/5o2u.wat | 7 + benchmarks/pldi2026/btree/5o3u.wat | 7 + benchmarks/pldi2026/btree/6o1u.wat | 7 + benchmarks/pldi2026/btree/6o2u.wat | 7 + benchmarks/pldi2026/btree/6o3u.wat | 7 + benchmarks/pldi2026/btree/7o1u.wat | 7 + benchmarks/pldi2026/btree/7o2u.wat | 7 + benchmarks/pldi2026/btree/7o3u.wat | 7 + benchmarks/pldi2026/btree/8o1u.wat | 7 + benchmarks/pldi2026/btree/8o2u.wat | 7 + benchmarks/pldi2026/btree/9o1u.wat | 7 + benchmarks/pldi2026/btree/9o2u.wat | 7 + benchmarks/pldi2026/btree/BTree.wast | 4080 ++++++++++++++++++++++++++ 22 files changed, 4227 insertions(+) create mode 100644 benchmarks/pldi2026/btree/BTree.wast diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index d5172a5e..cba10033 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index 2d0a90ae..cf478938 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index b9d56a09..9008544b 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index 17824b8c..db7d68a9 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 01e18274..b039177b 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 0a929b47..343a8127 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index e7c20f49..a900005f 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 8008797d..54e2939c 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 44eb9448..e4703532 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 961fe3dd..22c4b48c 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 02a3a0e9..c569b08f 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index 8d609fba..a3dc653b 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 33292ec4..4fd63a13 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 24fe6fd1..39e34e02 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index bfa1a2b1..d3659dda 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 1b9fee44..6e8e6518 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 783374a1..1d0d8049 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 9fb9a51a..df75ebc3 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index be3cc6b6..7c5dcb27 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index 73f3820f..c6007519 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 3ecf8dbf..7f699c1e 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -1,4 +1,11 @@ (module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) (memory $0 1) diff --git a/benchmarks/pldi2026/btree/BTree.wast b/benchmarks/pldi2026/btree/BTree.wast new file mode 100644 index 00000000..04a72159 --- /dev/null +++ b/benchmarks/pldi2026/btree/BTree.wast @@ -0,0 +1,4080 @@ +(module + (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) + + (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) + + (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) + + (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) + (memory $0 1) + + + (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree + (i32.const 0) + (local.get 0) + (i32.store) ;; store t at address 0 + + (i32.const 0) + (i32.const 1) + (i32.store offset=4) ;; store the number of nodes in the btree = 1 + + (i32.const 0) + (i32.const 65536) + (i32.store offset=8) ;; store the root addr + + (i32.const 1) ;; Now create root + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then + (i32.const 65536) ;; 64KiB = 65536 bytes + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + + (i32.const 65536) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + ) + ) + (i32.const 65536) ;; returns the address of the root + ) + + ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. + (func $btreeSearch (param i32) (param i32) (result i32) (local i32) + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n -1 + (i32.le_s) ;; i <= x.children-1 + (if + (then + (local.get 1) ;; k + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + (if + (then + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) ;; i + + (local.get 0) ;; x + (i32.load offset=4) ;; x.children + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.le_s) ;; i <= x.children - 1 + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.eq) + ;; k == x.keys[i] + (if (result i32) + (then + + (local.get 0) ;; save the address, which is x+8+i*4 + (i32.const 8) + (i32.add) ;; x+8 + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x+8+i*4 + + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + (else + (local.get 0) ;; x + (i32.load) ;; x is leaf? + (i32.const 1) ;; if == 1, then yes + (i32.eq) + (if (result i32) + (then + (i32.const -1) + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i + + (local.get 1) ;; k + + (call $btreeSearch) ;; btreeSearch(x.children[i], k) + + ) + ) + ) + ) + ) + + ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x + (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if ;; if we can grow memory + (then ;; get the number of nodes in the tree + (i32.const 0) + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address is 64KiB*(number of nodes+1) + (local.set 2) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + + (i32.load offset=8) ;; load the addr of the child in index i : y + + + (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child + (i32.const 1) + (i32.eq) ;; is y leaf? + (if + (then ;; yes + (local.get 2) ;; addr of new node z + (i32.const 1) + (i32.store) ;; store 1(TRUE) regarding if node is leaf + ) + (else ;; no + (local.get 2) ;; addr of new node z + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + ) + ) + + (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + + (i32.store offset=4) ;; store number of children = (t/2)-1 + + (i32.const 0) ;; now to store the keys + (local.set 3) ;; counter = 0 + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.const 1) + (i32.sub) ;; (t/2)-1 + (i32.eq) ;; counter == (t/2)-1 + (if + (then + + (br $loop_break) + ) + (else + + (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] + + (i32.const 4) + (local.get 3) ;; counter + + (i32.mul) ;; counter * 4 + + (i32.add) ;; addr + counter * 4 -> where the key is goint to be located + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.add) ;; counter + (t/2) + + (i32.mul) ;; counter + (t/2) *4 + + (i32.add) ;; y + counter + (t/2) *4 + (i32.load offset=8) ;; y.keys[counter + (t/2)] + + (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] + + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + + ) + ) + ) + ) + + (i32.const 0) + (local.set 3) ;; set counter back to 0 + + (i32.const 0) ;; check if x.children[i] is leaf + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + i*4 + (i32.load offset=8) ;; load the address of the child in index i = y + (i32.load) ;; get first i32 in child --> isLeaf + (i32.const 1) + (i32.ne) ;; is leaf? + + (if + (then ;; not leaf so we have to update the children + (block $loop_break + (loop $loop + + (local.get 3) ;; counter + + (i32.const 0) + (i32.load) ;; t + + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.eq) ;; counter == (t/2) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; now get z.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; counter*4 + + (i32.add) ;; (t-1)*4 + counter*4 + + (local.get 2) ;; z + (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) ;; get x.children[i].children[counter+(t/2)] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.add) ;; counter + t/2 + (i32.const 4) + (i32.mul) ;; counter+t/2 * 4 + + (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 + + (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 + (i32.load offset=8) ;; load the address of the child in index counter + t/2 + + (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] + + (local.get 3) ;; increment counter + (i32.const 1) + (i32.add) + (local.set 3) + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 + + (local.get 0) ;; x + + (i32.load offset=4) ;; get x.n + (local.set 3) ;; counter = x.n + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (local.get 3) ;; counter + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; get x.children[counter + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (i32.add) ;; (t-1)*4 + (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored + + (i32.const 0) ;; get x.children[counter] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (i32.add) ;; (t-1)*4 + (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (counter)*4 + (i32.load offset=8) ;; load the addr of the child in index (counter) + + (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (i32.const 0) ;; get x.children[i + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 1) + (i32.add) ;; i + 1 + (i32.const 4) + (i32.mul) ;; (i + 1)*4 + + (i32.add) ;; (t-1)*4 + (i + 1)*4 + + (local.get 0) ;; x + + (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child + + (local.get 2) ;; addr of z + (i32.store offset=8) ;; x.children[i+1] = z + + (local.get 0) ;; x + (i32.load offset=4) ;; get x.n + (i32.const 1) + (i32.sub) + (local.set 3) ;; counter = x.n -1 + + (block $loop_break + (loop $loop + (local.get 1) ;; i + (i32.const 1) + (i32.sub) ;; i-1 + (local.get 3) ;; counter + (i32.eq) ;; counter == i-1 + + (if + (then + (br $loop_break) + ) + (else + + (local.get 3) ;; get x.keys[counter + 1] ;; counter + (i32.const 1) + (i32.add) ;; counter + 1 + (i32.const 4) + (i32.mul) ;; (counter + 1)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key + + (local.get 3) ;; counter + (i32.const 4) + (i32.mul) ;; (counter)*4 + + (local.get 0) ;; x + (i32.add) ;; x +(counter)*4 + (i32.load offset=8) ;; load the key in index (counter) + + (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] + + (local.get 3) ;; decrement counter + (i32.const 1) + (i32.sub) + (local.set 3) + (br $loop) + ) + ) + + ) + ) + + (local.get 1) ;; get x.keys[i] + (i32.const 4) + (i32.mul) ;; i*4 + + (local.get 0) ;; x + (i32.add) ;; x +i*4 --> addr of the key + + (i32.const 0) ;; get x.children[i].keys[t/2] + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; t/2 -1 + + (i32.const 4) + (i32.mul) ;; (t/2)-1 *4 + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 1) ;; i + (i32.const 4) + (i32.mul) ;; (i)*4 + + (i32.add) ;; (t-1)*4 + (i)*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i)*4 + (i32.load offset=8) ;; load the address of the child in index (i) + + (i32.add) ;; y + (t/2)-1 *4 + (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] + + (i32.store offset=8) ;; store the new key in the addr + + (local.get 0) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) ;; x.n + 1 + (i32.store offset=4) ;; x.n = x.n + 1 + ) + ) + ) + + ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert + (func $btreeInsertNonFull (param i32) (param i32) (local i32) + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.const 1) + (i32.sub) ;; x.n -1 + (local.set 2) ;; i = x.n -1 + + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (block $loop_break + (loop $loop + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + + (if (result i32) + (then + (local.get 1) ;; k + (local.get 0) ;; x + ;; x+4*i + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + (i32.lt_s) ;; k < x.keys[i] + ) + (else + (i32.const 0) + ) + ) + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i <= 0? + (i32.and) + + (if + (then + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i *4 + + (i32.add) ;; x + i *4 --> addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 2) ;; i = i-1 + (br $loop) + + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.mul) ;; i+1 *4 + + (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.keys[i+1] = k + + (local.get 0) + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;; x.n = x.n +1 + + ) + (else ;; x is not leaf + (block $loop_break + (loop $loop + + (local.get 2) ;; i + (i32.const 0) + (i32.ge_s) ;; i >= 0 + + (if + (then + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.lt_s) ;; k < x.keys[i] + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i -1 + (local.set 2) ;; i = i-1 + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + + (i32.const 1) + (i32.add) + + (local.set 2) ;;i = i+1 + + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y + (i32.load offset=8) ;; load the address of the child in index i = y + + (i32.load offset=4) ;; get y.n + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; y.n == t-1 --> node is full + (if + (then + (local.get 0) ;; x + + (local.get 2) ;; i + (call $btreeSplitChild) + + (local.get 1) ;; k + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k>x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i+1 + ) + ) + ) + ) + + (i32.const 0) ;; get x.children[i] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; load the address of the child in index i = y + + (local.get 1) ;; k + + (call $btreeInsertNonFull) + + ) + ) + ) + + (func $btreeInsert (param i32) (result i32) (local i32) (local i32) + (i32.const 0) + (i32.load offset=8) ;; root addr + (local.tee 2) ;; set r + + (i32.load offset=4) ;; r.n + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.eq) ;; r.n == t-1 --> root is full + (if (result i32) + (then + + (i32.const 1) ;; create a new node + (memory.grow) ;; create new page + (i32.const -1) + (i32.ne) + (if (result i32) ;; if we can grow memory + (then + (i32.const 0) ;; get the number of nodes in the tree + (i32.load offset=4) ;; number of nodes in the tree + (i32.const 1) + (i32.add) ;; number of nodes + 1 + (i32.const 65536) + (i32.mul) ;; address of s is 64KiB*(number of nodes+1) + (local.set 1) + + (i32.const 0) ;; change number of nodes + (i32.const 0) + (i32.load offset=4) + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; set number of nodes to + 1 + + (i32.const 0) + (local.get 1) ;; s + (i32.store offset=8) ;; root addr is now s + + (local.get 1) ;; s + (i32.const 0) + (i32.store) ;; store 0(FALSE) regarding if node is leaf + + (local.get 1) ;; now store number of keys + (i32.const 0) + (i32.store offset=4) ;; store number of keys = 0 + + (i32.const 0) ;; store children addresses + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 1) ;; x + (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located + (local.get 2) + + (i32.store offset=8) ;; s.children[0] = r + + (local.get 1) ;; s + (i32.const 0) + + (call $btreeSplitChild) + + (local.get 1) ;; s + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 1) ;; return the address of the new root + ) + (else + (i32.const -1) ;; return -1 because we could not create a new node + ) + ) + ) + (else + (local.get 2) ;; r + (local.get 0) ;; k + (call $btreeInsertNonFull) + (local.get 2) ;; return the address of the root, which is the same + ) + ) + ) + + ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) + (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) + (local.get 0) ;; x + (i32.load) ;; get first i32 --> isLeaf + (i32.const 1) + (i32.eq) ;; is leaf? + (if + (then ;; x is leaf + (i32.const 0) + (local.set 2) ;; i = 0 + (block $loop_break + (loop $loop + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (local.get 2) ;; i + + (i32.eq) ;; i == x.n + (if + (then + (br $loop_break) ;; break from loop + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + + (i32.eq) ;; k == x.keys[i] + (if + (then + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $while_break + (loop $while + (local.get 3) ;; j + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n-1 + (i32.eq) ;; j == x.n-1 + (if + (then + (br $while_break) + ) + (else + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + + (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored + + (local.get 0) ;; x + + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.mul) ;; j+1 *4 + + (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $while) + ) + ) + + ) + ) + (local.get 0) ;; x + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.n = x.n -1 + (br $loop_break) + ) + + ) + ) + + ) + (i32.const 1) + (local.get 2) + (i32.add) + (local.set 2) ;; i = i+1 + (br $loop) ;; continue + ) + ) + ) + (else ;; x is not leaf + + (i32.const 0) ;;get the index of the appropriate child/key + (local.set 2) ;; i = 0 + + (block $loop_break + (loop $loop + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (if (result i32) + (then + (local.get 1) ;; k + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (i32.gt_s) ;; k > x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (local.get 2) ;; i + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.le_s) ;; i <= x.n - 1 + + (i32.and) ;; i <= x.n - 1 && k > x.keys[i] + + (if + (then + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (local.set 2) ;; i = i + 1 + + (br $loop) + ) + (else + (br $loop_break) + ) + ) + ) + ) + (local.get 2) + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.lt_s) ;; i < x.n + (if (result i32) + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[i] + + (local.get 1) ;; k + (i32.eq) ;; k == x.keys[i] + ) + (else + (i32.const 0) + ) + ) + (if + (then ;; key is present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.tee 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i].n >= t/2 + (if + (then + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.sub) ;; index = x.c[i].n - 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] + + (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] + + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i+1] + (local.tee 5) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (local.get 5) ;; x.c[i+1] + (local.get 5) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[0] + (call $btreeDelete) + (drop) + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + ) + (else + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i *4 + (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored + + (local.get 1) ;; k + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k + + (i32.const 0) ;; now merge x.c[i] with x.c[i+1] + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + (i32.add) ;; (t-1)*4 + i+1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + + (if ;; j == x.c[i+1].n + (then + (br $loop_break) + ) + (else + + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n + j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + + ) + + ) + ) + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n +1 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.add) + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + + (i32.const 0) ;; now adjust the children + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.get 3) ;; j + (i32.add) ;; index = x.c[i].n+j + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored + + (i32.const 0) ;;get x.c[i+1].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x.c[i+1] + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + (i32.const 1) + (i32.sub) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; j*4 + (i32.add) ;; x + j*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.add) + (i32.mul) ;; j+1*4 + (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + + ) + ) + + (local.get 2) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = i+1 + + (block $loop_break + (loop $loop + (local.get 0) + (i32.load offset=4) + + (local.get 3) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.add) ;; j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + (local.get 0) + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + (i32.store offset=4) ;; x.n = x.n-1 + + (local.get 5) ;; x.c[i] + (local.get 1) ;; k + + (call $btreeDelete) + (drop) + + ) + ) + + ) + ) + + ) + (else ;; key not present in node x + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 4) + (i32.mul) ;; i*4 + + (i32.add) ;; (t-1)*4 + i*4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located + (i32.load offset=8) ;; x.c[i] + + (local.set 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) + (i32.const 1) + (i32.sub) ;; t/2 - 1 + + (i32.eq) + + (if + (then + (i32.const -1) + (local.set 4) ;; changed = -1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.le_s) ;; i+1 <= x.n + + (if + (then + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i+1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i+1].n >= t/2 + + (if + (then + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.const 1) + (i32.sub) ;; index = t/2 -1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] + + (local.get 5) + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + + (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 + + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] + (i32.load offset=8) ;; x.c[i+1].keys[0] + + (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] + + (local.get 5) + (i32.load) ;; x.c[i] is leaf? + (i32.const 1) + (i32.ne) + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + + (i32.const 0) ;;get x.c[i].c[t/2] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; index = t/2 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] + + (i32.const 0) ;;get x.c[i+1].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[0] + + (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] + ) + ) + + (local.get 5) ;; x.c[i] + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + (i32.store offset=4) ;; x.c[i].n = t/2 + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j+1] + + (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if ;; if x.c[i] is not leaf, we have to adjust children + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j+1 + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j+1] + + (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j+1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located + (i32.load offset=8) + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + (i32.const 0) + (i32.ge_s) ;; i -1 >= 0 + + (i32.and) ;; changed == -1 && i -1 >= 0 + + (if + (then + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 0) + (i32.load) ;; t + (i32.const 2) + (i32.div_s) ;; t/2 + + (i32.ge_s) ;; x.c[i-1].n >= t/2 + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (local.set 3) ;; j = x.c[i].n + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] + (i32.load offset=8) ;; x.c[i].keys[j-1] + + (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + + (if + (then + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (local.set 3) ;; j = x.c[i].n + 1 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) + (i32.eq) + + (if + (then + (br $loop_break) + ) + (else + (i32.const 0) ;;get x.c[i].c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located + + (i32.const 0) ;;get x.c[i].c[j-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; j + (i32.const 1) + (i32.sub) ;; j-1 + (i32.const 4) + (i32.mul) ;; j *4 + + (i32.add) ;; (t-1)*4 + j *4 + + (local.get 5) ;; x.c[i] + (i32.add) + (i32.load offset=8) ;; x.c[i].c[j-1] + + (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] + + (local.get 3) + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = j-1 + + (br $loop) + ) + ) + ) + ) + ) + ) + + (local.get 5) + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) + (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 + + (local.get 5) ;; x.c[i] + (i32.const 4) + (i32.const 0) ;; index = 0 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i-1] + + (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) + (i32.load offset=4) ;; x.c[i-1].n + + (i32.const 1) + (i32.sub) + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; index = i-1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + (i32.load offset=8) + + (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + + (i32.const 0) ;; get x.c[i].c[0] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located + + (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (i32.const 1) + (i32.add) ;; index = x.c[i-1.n + 1] + + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] + + (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] + + ) + ) + (i32.const 0) + (local.set 4) ;; changed = 0 + ) + ) + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) + (if ;; changed == -1? + (then + + (local.get 2) ;; we have to merge x.c[i] with one sibling;; i + (i32.const 1) + (i32.add) ;; i+1 + + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + + (i32.le_s) + (if ;; i+1 <= x.n + (then + + (local.get 5) ;; merge with right sibling;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) ;; index = x.c[i].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + (local.get 5) ;; x.c[i] + (i32.const 4) + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i+1].keys[j] + + (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i+1].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 5) + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] + + (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1].c[j] + + (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (local.get 5) ;; x.c[i] + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.const 0) ;;get x.c[i+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i+1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i+1] + (i32.load offset=4) ;; x.c[i+1].n + + (i32.add) ;; x.c[i].n + x.c[i+1].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 + + (local.get 2) ;; i + (i32.const 1) + (i32.add) ;; i+1 + (local.set 3) ;; j = i+1 + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + ) + ) + (local.get 2) ;; i + (local.set 3) ;; j = i + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + + (i32.const 0) + (local.set 4) ;; changed = 0 + + ) + ) + + (local.get 4) ;; changed + (i32.const -1) + (i32.eq) ;; changed == -1 ? + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) ;; i - 1 + + (i32.const 0) + (i32.ge_s) ;; i - 1 >= 0? + + (i32.and) ;; changed == -1 && i - 1 >= 0 + (if + (then + + (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; index = x.c[i-1].n + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] + + (local.get 0) ;; x + (i32.const 4) + (local.get 2) ;; index = i + (i32.const 1) + (i32.sub) ;; index = i-1 + + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] + (i32.load offset=8) ;; x.keys[i] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] + + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;; x.c[i-1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.const 4) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] + + (local.get 5) ;; x.c[i] + (i32.const 4) + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.c[i].keys[j] + + (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + + (local.get 5) + (i32.load) + (i32.const 1) + (i32.ne) + (if + (then + (i32.const 0) + (local.set 3) ;; j = 0 + + (block $loop_break + (loop $loop + (local.get 3) ;; j + + (local.get 5) ;; x.c[i] + (i32.load offset=4) ;; x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + 1 + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) + (local.get 3) + (i32.add) + (i32.const 1) + (i32.add) ;; index = x.c[i-1].n+j+1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 5) ;; x.c[i] + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i].c[j] + + (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + (br $loop) + ) + ) + + ) + ) + ) + ) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (i32.load offset=4) ;; x.c[i-1].n + + (local.get 5) + (i32.load offset=4) ;; x.c[i].n + + (i32.add) ;; x.c[i-1].n + x.c[i].n + (i32.const 1) + (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 + + (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 + + (local.get 2) ;; i + (local.set 3) ;; j = i + + (block $loop_break ;; re-organize x + (loop $loop + + (local.get 3) + + (local.get 0) + (i32.load offset=4) ;; x.n + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (i32.const 0) ;;get x.c[j] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) ;; index = j + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + + (i32.const 0) ;;get x.c[j+1] + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.const 4) + (i32.mul) ;; i-1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] + (i32.load offset=8) ;; x.c[j+1] + + (i32.store offset=8) ;; x.c[j] = x.c[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (local.set 3) ;; j = i - 1 + (block $loop_break + (loop $loop + + (local.get 3) ;; j + + (local.get 0) + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) + + (i32.eq) + (if + (then + (br $loop_break) + ) + (else + + (local.get 0) ;; x + (i32.const 4) + + (local.get 3) ;; index = j + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 ;; addr of x.keys[j] + + (local.get 0) ;; x + (i32.const 4) + (local.get 3) + (i32.const 1) + (i32.add) ;; index = j + 1 + (i32.mul) ;; i*4 + (i32.add) ;; x + i*4 + (i32.load offset=8) ;; x.keys[j+1] + + (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] + + (local.get 3) + (i32.const 1) + (i32.add) + (local.set 3) ;; j = j + 1 + + (br $loop) + + ) + ) + + ) + ) + (local.get 0) ;; x + (local.get 0) ;; x + (i32.load offset=4) ;; x.n + (i32.const 1) + (i32.sub) ;; x.n - 1 + (i32.store offset=4) ;; x.n = x.n - 1 + ) + ) + ) + ) + ) + ) + (local.get 4) + (i32.const -1) + (i32.eq) + (if ;; changed == -1? if yes, we merged with left sibling + (then + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (local.get 2) ;; i + (i32.const 1) + (i32.sub) + (i32.const 4) + (i32.mul) ;; i+1 *4 + + (i32.add) ;; (t-1)*4 + i-1 *4 + + (local.get 0) ;; x + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; x.c[i-1] + (local.get 1) + (call $btreeDelete) + (drop) + ) + (else + (local.get 5) ;; x.c[i] + (local.get 1) + (call $btreeDelete) + (drop) + ) + ) + + ) + ) + ) ;; end of if x is not leaf + ) + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.load offset=4) + (i32.const 0) + (i32.eq) + (if ;; if root is empty + (then + (i32.const 0) + + (i32.const 0) + (i32.load) ;; t + (i32.const 1) + (i32.sub) ;; t-1 + (i32.const 4) + (i32.mul) ;; (t-1)*4 + + (i32.const 0) ;; index = 0 + (i32.const 4) + (i32.mul) ;; i *4 + + (i32.add) ;; (t-1)*4 + i *4 + + (i32.const 0) + (i32.load offset=8) ;; root addr + (i32.add) ;; x + (t-1)*4 + (i32.load offset=8) ;; root.c[0] + + (i32.store offset=8) ;; root = root.c[0] + ) + ) + + (i32.const 0) + (i32.load offset=8) ;; root addr + ) + + + (func $main + (local i32) + (i32.const 4) ;;create a tree with degree 4 + (call $createBtree) + (local.set 0) + + ;; 5 symbolic variables w/ order + ;; a and b + (sym_int32 "a") + (sym_int32 "b") + (i32.ne) + + (;);;c + (sym_int32 "c") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "c") + (get_sym_int32 "b") + (i32.ne);) + + (;);;d + (sym_int32 "d") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "d") + (get_sym_int32 "c") + (i32.ne);) + + (;;;e + (sym_int32 "e") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "e") + (get_sym_int32 "d") + (i32.ne);) + + (;);; f + (sym_int32 "f") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "f") + (get_sym_int32 "e") + (i32.ne) + + ;; g + (sym_int32 "g") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "g") + (get_sym_int32 "f") + (i32.ne) + + ;; z + (sym_int32 "z") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "b") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "c") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "d") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "e") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "z") + (get_sym_int32 "g") + (i32.ne);) + + + + ;; logical order: a>b>c>d>e>f>g>z + (get_sym_int32 "a") + (get_sym_int32 "b") + (i32.gt_s) + + (;(get_sym_int32 "b") + (get_sym_int32 "c") + (i32.gt_s);) + + (;(get_sym_int32 "c") + (get_sym_int32 "d") + (i32.gt_s);) + + (;(get_sym_int32 "d") + (get_sym_int32 "e") + (i32.gt_s);) + + (;(get_sym_int32 "e") + (get_sym_int32 "f") + (i32.gt_s) + + (get_sym_int32 "f") + (get_sym_int32 "g") + (i32.gt_s) + + (get_sym_int32 "g") + (get_sym_int32 "z") + (i32.gt_s);) + + + (i32.and) + + ;; 2 symbolic variables w/o order + ;; h + (sym_int32 "h") + (sym_int32 "a") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "b") + (i32.ne) + + (;(get_sym_int32 "h") + (get_sym_int32 "c") + (i32.ne);) + + (;(get_sym_int32 "h") + (get_sym_int32 "d") + (i32.ne);) + + (;(get_sym_int32 "h") + (get_sym_int32 "e") + (i32.ne);) + + (;(get_sym_int32 "h") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "h") + (get_sym_int32 "z") + (i32.ne);) + + + + ;; i + (sym_int32 "i") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "b") + (i32.ne) + + (;(get_sym_int32 "i") + (get_sym_int32 "c") + (i32.ne);) + + (;(get_sym_int32 "i") + (get_sym_int32 "d") + (i32.ne);) + + (;(get_sym_int32 "i") + (get_sym_int32 "e") + (i32.ne);) + + (;(get_sym_int32 "i") + (get_sym_int32 "f") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "g") + (i32.ne) + + (get_sym_int32 "i") + (get_sym_int32 "z") + (i32.ne);) + + + (get_sym_int32 "i") + (get_sym_int32 "h") + (i32.ne) + + + ;; j + (sym_int32 "j") + (get_sym_int32 "a") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "b") + (i32.ne) + + (;(get_sym_int32 "j") + (get_sym_int32 "c") + (i32.ne);) + + (;(get_sym_int32 "j") + (get_sym_int32 "d") + (i32.ne);) + + (;(get_sym_int32 "j") + (get_sym_int32 "e") + (i32.ne);) + + (;(get_sym_int32 "j") + (get_sym_int32 "f") + (i32.ne) + + (;(get_sym_int32 "j") + (get_sym_int32 "g") + (i32.ne););) + + (get_sym_int32 "j") + (get_sym_int32 "h") + (i32.ne) + + (get_sym_int32 "j") + (get_sym_int32 "i") + (i32.ne) + + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assume) + + ;; insert variables + (get_sym_int32 "a") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "b") + (call $btreeInsert) + (local.set 0) + (;(get_sym_int32 "c") + (call $btreeInsert) + (local.set 0);) + (;(get_sym_int32 "d") + (call $btreeInsert) + (local.set 0);) + (;(get_sym_int32 "e") + (call $btreeInsert) + (local.set 0);) + (;(get_sym_int32 "f") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "g") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "z") + (call $btreeInsert) + (local.set 0);) + (get_sym_int32 "h") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "i") + (call $btreeInsert) + (local.set 0) + (get_sym_int32 "j") + (call $btreeInsert) + (local.set 0) + + (print_btree) + + ;; search for variables & check that they were inserted + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (;(local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.ne);) + + (;(local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.ne);) + + (;(local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.ne);) + + (;(local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "z") + (call $btreeSearch) + (i32.const -1) + (i32.ne);) + + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (local.get 0) + (get_sym_int32 "j") + (call $btreeSearch) + (i32.const -1) + (i32.ne) + + (i32.and) + (i32.and) + (i32.and) + (i32.and) + (sym_assert) + + ;; delete & check that it was deleted + ;; a + (local.get 0) + (get_sym_int32 "a") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "a") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; b + (local.get 0) + (get_sym_int32 "b") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "b") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + (;);; c + (local.get 0) + (get_sym_int32 "c") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "c") + (call $btreeSearch) + (i32.const -1) + (i32.eq);) + + (;);; d + (local.get 0) + (get_sym_int32 "d") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "d") + (call $btreeSearch) + (i32.const -1) + (i32.eq);) + + ;; e + (;(local.get 0) + (get_sym_int32 "e") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "e") + (call $btreeSearch) + (i32.const -1) + (i32.eq);) + + (;);; f + (local.get 0) + (get_sym_int32 "f") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "f") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; g + (local.get 0) + (get_sym_int32 "g") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "g") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; z + (local.get 0) + (get_sym_int32 "z") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "z") + (call $btreeSearch) + (i32.const -1) + (i32.eq);) + + ;; h + (local.get 0) + (get_sym_int32 "h") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "h") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + ;; i + (local.get 0) + (get_sym_int32 "i") + (call $btreeDelete) + (local.set 0) + + (local.get 0) + (get_sym_int32 "i") + (call $btreeSearch) + (i32.const -1) + (i32.eq) + + + (print_btree) + + (i32.and) + (i32.and) + (i32.and) + + (sym_assert) + + + + ) + (export "main" (func $main)) + +) +(invoke "main") From c82a8e3e6ee907d03a3979e6c5c95feb4ec919ee Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:21:19 -0400 Subject: [PATCH 58/82] replace call to i32.symbolic with external call --- benchmarks/pldi2026/btree/2o2u.wat | 8 ++++---- benchmarks/pldi2026/btree/2o3u.wat | 10 +++++----- benchmarks/pldi2026/btree/3o1u.wat | 8 ++++---- benchmarks/pldi2026/btree/3o2u.wat | 10 +++++----- benchmarks/pldi2026/btree/3o3u.wat | 12 ++++++------ benchmarks/pldi2026/btree/4o1u.wat | 10 +++++----- benchmarks/pldi2026/btree/4o2u.wat | 12 ++++++------ benchmarks/pldi2026/btree/4o3u.wat | 14 +++++++------- benchmarks/pldi2026/btree/5o1u.wat | 12 ++++++------ benchmarks/pldi2026/btree/5o2u.wat | 14 +++++++------- benchmarks/pldi2026/btree/5o3u.wat | 16 ++++++++-------- benchmarks/pldi2026/btree/6o1u.wat | 14 +++++++------- benchmarks/pldi2026/btree/6o2u.wat | 16 ++++++++-------- benchmarks/pldi2026/btree/6o3u.wat | 18 +++++++++--------- benchmarks/pldi2026/btree/7o1u.wat | 16 ++++++++-------- benchmarks/pldi2026/btree/7o2u.wat | 18 +++++++++--------- benchmarks/pldi2026/btree/7o3u.wat | 20 ++++++++++---------- benchmarks/pldi2026/btree/8o1u.wat | 18 +++++++++--------- benchmarks/pldi2026/btree/9o1u.wat | 20 ++++++++++---------- benchmarks/pldi2026/btree/9o2u.wat | 22 +++++++++++----------- 20 files changed, 144 insertions(+), 144 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index cba10033..62315a44 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3555,9 +3555,9 @@ ;; 2 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b @@ -3571,7 +3571,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3581,7 +3581,7 @@ ;; i (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index cf478938..fe9a9c90 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3555,9 +3555,9 @@ ;; 2 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b @@ -3571,7 +3571,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (sym_int32 "a") (i32.ne) @@ -3581,7 +3581,7 @@ ;; i (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3596,7 +3596,7 @@ ;; j (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index 9008544b..ebf7c304 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3555,14 +3555,14 @@ ;; 3 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3588,7 +3588,7 @@ ;; 1 symbolic variable w/o order ;; h (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index db7d68a9..16fb2ade 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3555,14 +3555,14 @@ ;; 3 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3588,7 +3588,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3602,7 +3602,7 @@ ;; i (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index b039177b..1598c2be 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3555,14 +3555,14 @@ ;; 3 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3588,7 +3588,7 @@ ;; 3 symbolic variables w/o order ;; h (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3602,7 +3602,7 @@ ;; i (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3621,7 +3621,7 @@ ;; j (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 343a8127..b1eb3c93 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3555,14 +3555,14 @@ ;; 4 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3609,7 +3609,7 @@ ;; 1 symbolic variables w/o order ;; h (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index a900005f..51cc1247 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3555,14 +3555,14 @@ ;; 4 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3609,7 +3609,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3627,7 +3627,7 @@ ;; i (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 54e2939c..4078da38 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3555,14 +3555,14 @@ ;; 4 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3609,7 +3609,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3627,7 +3627,7 @@ ;; i (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3650,7 +3650,7 @@ ;; j (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index e4703532..4f017f4c 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3637,7 +3637,7 @@ ;; 1 symbolic variable w/o order ;; h (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 22c4b48c..f7089ed7 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3637,7 +3637,7 @@ ;; 2 symbolic variable w/o order ;; h (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3659,7 +3659,7 @@ ;; i (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index c569b08f..b100e571 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3637,7 +3637,7 @@ ;; 3 symbolic variable w/o order ;; h (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3659,7 +3659,7 @@ ;; i (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3685,7 +3685,7 @@ ;; j (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index a3dc653b..bec696f5 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3555,14 +3555,14 @@ ;; 6 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3671,7 +3671,7 @@ ;; 1 symbolic variables w/o order ;; h (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 4fd63a13..f1bb7de7 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3555,14 +3555,14 @@ ;; 6 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3671,7 +3671,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3697,7 +3697,7 @@ ;; i (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 39e34e02..89c8c8f7 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3555,14 +3555,14 @@ ;; 6 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3671,7 +3671,7 @@ ;; 3 symbolic variables w/o order ;; h (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3697,7 +3697,7 @@ ;; i (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3727,7 +3727,7 @@ ;; i (i32.const 1040) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index d3659dda..8167b2d5 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3706,7 +3706,7 @@ ;; 1 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 6e8e6518..7223a70f 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3706,7 +3706,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3737,7 +3737,7 @@ ;; i (i32.const 1040) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 1d0d8049..0b3bf50a 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3706,7 +3706,7 @@ ;; 3 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3737,7 +3737,7 @@ ;; i (i32.const 1040) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3771,7 +3771,7 @@ ;; i (i32.const 1042) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index df75ebc3..f53b1c33 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3652,7 +3652,7 @@ ;; x (i32.const 1044) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3748,7 +3748,7 @@ ;; 1 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index c6007519..f26a939d 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -3555,14 +3555,14 @@ ;; 5 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3652,7 +3652,7 @@ ;; x (i32.const 1044) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3682,7 +3682,7 @@ ;; y (i32.const 1046) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3795,7 +3795,7 @@ ;; 1 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 7f699c1e..6beffc85 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -3555,14 +3555,14 @@ ;; 9 symbolic variables w/ order ;; a and b (i32.const 1024) - (i32.symbolic) + (call $i32.symbolic) (i32.const 1026) - (i32.symbolic) + (call $i32.symbolic) (i32.ne) ;;c (i32.const 1028) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3572,7 +3572,7 @@ ;;d (i32.const 1030) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3586,7 +3586,7 @@ ;;e (i32.const 1032) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3604,7 +3604,7 @@ ;; f (i32.const 1034) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3626,7 +3626,7 @@ ;; g (i32.const 1036) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3652,7 +3652,7 @@ ;; x (i32.const 1044) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3682,7 +3682,7 @@ ;; y (i32.const 1046) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3795,7 +3795,7 @@ ;; 2 symbolic variables w/o order ;; h (i32.const 1038) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) @@ -3833,7 +3833,7 @@ ;; i (i32.const 1040) - (i32.symbolic) + (call $i32.symbolic) (get_sym_int32 "a") (i32.ne) From 3e6964ec20473acb4b6fb722ec41b89c4a18fd33 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:44:44 -0400 Subject: [PATCH 59/82] a normalize script --- benchmarks/pldi2026/btree/normalize.py | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 benchmarks/pldi2026/btree/normalize.py diff --git a/benchmarks/pldi2026/btree/normalize.py b/benchmarks/pldi2026/btree/normalize.py new file mode 100644 index 00000000..ab02461d --- /dev/null +++ b/benchmarks/pldi2026/btree/normalize.py @@ -0,0 +1,31 @@ +from pathlib import Path +import re + +pat = re.compile( + r'\(data\b\s+\$\S+\s+\(i32\.const\s+([0-9]+)\)\s*"((?:[^"\\]|\\.)*)"\)' +) + +def get_mapping(f: Path) -> list[tuple[int, str]]: + for line in f.read_text().splitlines(): + for m in pat.finditer(line): + base_str = m.group(1) + mapping_str = m.group(2) + keys = mapping_str.split("\\00") + assert(keys[-1] == "") + keys = keys[:-1] + return [(int(base_str) + i * 2, k) for i, k in enumerate(keys)] + + +def main(): + for file in Path(__file__).parent.glob("*.wat"): + mapping = get_mapping(file) + print(f"Mapping for {file.name}: {mapping}") + for addr, key in mapping: + # replace (get_sym_int32 "{key}") to (i32.const {addr})\n\t(call $i32.symbolic) in the file + file_contents = file.read_text() + file_contents = file_contents.replace(f'(get_sym_int32 "{key}")', f'(i32.const {addr})\n\t\t(call $i32.symbolic)') + file.write_text(file_contents) + + +if __name__ == "__main__": + main() From 46df39c4130e9ac8e8c9b7baac50470fb5f8b1d1 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:46:35 -0400 Subject: [PATCH 60/82] replace sym_assume with (call $i32.sym_assume) --- benchmarks/pldi2026/btree/2o2u.wat | 2 +- benchmarks/pldi2026/btree/2o3u.wat | 2 +- benchmarks/pldi2026/btree/3o1u.wat | 2 +- benchmarks/pldi2026/btree/3o2u.wat | 2 +- benchmarks/pldi2026/btree/3o3u.wat | 2 +- benchmarks/pldi2026/btree/4o1u.wat | 2 +- benchmarks/pldi2026/btree/4o2u.wat | 2 +- benchmarks/pldi2026/btree/4o3u.wat | 2 +- benchmarks/pldi2026/btree/5o1u.wat | 2 +- benchmarks/pldi2026/btree/5o2u.wat | 2 +- benchmarks/pldi2026/btree/5o3u.wat | 2 +- benchmarks/pldi2026/btree/6o1u.wat | 2 +- benchmarks/pldi2026/btree/6o2u.wat | 2 +- benchmarks/pldi2026/btree/6o3u.wat | 2 +- benchmarks/pldi2026/btree/7o1u.wat | 2 +- benchmarks/pldi2026/btree/7o2u.wat | 2 +- benchmarks/pldi2026/btree/7o3u.wat | 2 +- benchmarks/pldi2026/btree/8o1u.wat | 2 +- benchmarks/pldi2026/btree/8o2u.wat | 2 +- benchmarks/pldi2026/btree/9o1u.wat | 2 +- benchmarks/pldi2026/btree/9o2u.wat | 2 +- benchmarks/pldi2026/btree/BTree.wast | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 62315a44..de69374d 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3598,7 +3598,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index fe9a9c90..dba9a833 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3622,7 +3622,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index ebf7c304..5c4d815e 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3604,7 +3604,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index 16fb2ade..e70aa6d1 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3626,7 +3626,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 1598c2be..0ebe5310 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3654,7 +3654,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index b1eb3c93..e04b2766 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3630,7 +3630,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 51cc1247..5b2b5a3c 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3657,7 +3657,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 4078da38..d5ed711f 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3690,7 +3690,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 4f017f4c..b2593f87 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3663,7 +3663,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index f7089ed7..7759304d 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3695,7 +3695,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index b100e571..14212a7c 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3732,7 +3732,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index bec696f5..237bb88c 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3701,7 +3701,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index f1bb7de7..71f68a58 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3738,7 +3738,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 89c8c8f7..734799db 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3780,7 +3780,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 8167b2d5..49360bee 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3742,7 +3742,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 7223a70f..e7a6a095 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3785,7 +3785,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 0b3bf50a..90e04a3c 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -3832,7 +3832,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index f53b1c33..3c95b959 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3789,7 +3789,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index 7c5dcb27..f8a32377 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -3826,7 +3826,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index f26a939d..f0b751cb 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -3842,7 +3842,7 @@ (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 6beffc85..f417dd5a 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -3894,7 +3894,7 @@ (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") diff --git a/benchmarks/pldi2026/btree/BTree.wast b/benchmarks/pldi2026/btree/BTree.wast index 04a72159..86ddc11b 100644 --- a/benchmarks/pldi2026/btree/BTree.wast +++ b/benchmarks/pldi2026/btree/BTree.wast @@ -3828,7 +3828,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assume) + (call $i32.sym_assume) ;; insert variables (get_sym_int32 "a") From 6425d3808159a30a1ac98e41b6d1e337637c4297 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:47:27 -0400 Subject: [PATCH 61/82] remove print_btree, it's a dummy instruction only implemented in wasp --- benchmarks/pldi2026/btree/2o1u.wat | 4 ++-- benchmarks/pldi2026/btree/2o2u.wat | 4 ++-- benchmarks/pldi2026/btree/2o3u.wat | 4 ++-- benchmarks/pldi2026/btree/3o1u.wat | 4 ++-- benchmarks/pldi2026/btree/3o2u.wat | 4 ++-- benchmarks/pldi2026/btree/3o3u.wat | 4 ++-- benchmarks/pldi2026/btree/4o1u.wat | 4 ++-- benchmarks/pldi2026/btree/4o2u.wat | 4 ++-- benchmarks/pldi2026/btree/4o3u.wat | 4 ++-- benchmarks/pldi2026/btree/5o1u.wat | 4 ++-- benchmarks/pldi2026/btree/5o2u.wat | 4 ++-- benchmarks/pldi2026/btree/5o3u.wat | 4 ++-- benchmarks/pldi2026/btree/6o1u.wat | 4 ++-- benchmarks/pldi2026/btree/6o2u.wat | 4 ++-- benchmarks/pldi2026/btree/6o3u.wat | 4 ++-- benchmarks/pldi2026/btree/7o1u.wat | 4 ++-- benchmarks/pldi2026/btree/7o2u.wat | 4 ++-- benchmarks/pldi2026/btree/7o3u.wat | 4 ++-- benchmarks/pldi2026/btree/8o1u.wat | 4 ++-- benchmarks/pldi2026/btree/8o2u.wat | 4 ++-- benchmarks/pldi2026/btree/9o1u.wat | 4 ++-- benchmarks/pldi2026/btree/9o2u.wat | 4 ++-- benchmarks/pldi2026/btree/BTree.wast | 4 ++-- 23 files changed, 46 insertions(+), 46 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o1u.wat b/benchmarks/pldi2026/btree/2o1u.wat index d57fe9d2..40df604c 100644 --- a/benchmarks/pldi2026/btree/2o1u.wat +++ b/benchmarks/pldi2026/btree/2o1u.wat @@ -3602,7 +3602,7 @@ (call $btreeInsert) (local.set 0) - ;; (print_btree) + ;; ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3663,7 +3663,7 @@ ;; (print_stack) - ;; (print_btree) + ;; ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index de69374d..579fffd9 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3614,7 +3614,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3685,7 +3685,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index dba9a833..24540db9 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3641,7 +3641,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3730,7 +3730,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index 5c4d815e..20905c9a 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3620,7 +3620,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3689,7 +3689,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index e70aa6d1..8f33dccf 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3645,7 +3645,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3734,7 +3734,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 0ebe5310..06398244 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3676,7 +3676,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3784,7 +3784,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index e04b2766..040e9282 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3649,7 +3649,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3737,7 +3737,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 5b2b5a3c..570c68cf 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3679,7 +3679,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3787,7 +3787,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index d5ed711f..4d32a327 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3715,7 +3715,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3842,7 +3842,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index b2593f87..457043e3 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3685,7 +3685,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3792,7 +3792,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 7759304d..a1e4bade 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3720,7 +3720,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3846,7 +3846,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 14212a7c..0c4efe00 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3760,7 +3760,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3905,7 +3905,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index 237bb88c..c2280ddf 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3726,7 +3726,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3852,7 +3852,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 71f68a58..77712bc1 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3766,7 +3766,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3911,7 +3911,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 734799db..67f7abc6 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3811,7 +3811,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3975,7 +3975,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 49360bee..65d91bfe 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3770,7 +3770,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3916,7 +3916,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index e7a6a095..97f96b66 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3816,7 +3816,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3981,7 +3981,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 90e04a3c..2ed4b70c 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -3866,7 +3866,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -4050,7 +4050,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 3c95b959..eb24fdf7 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3821,7 +3821,7 @@ (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -3985,7 +3985,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index f8a32377..4e39fe76 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -3861,7 +3861,7 @@ (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -4044,7 +4044,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index f0b751cb..647fecc2 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -3877,7 +3877,7 @@ (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -4060,7 +4060,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index f417dd5a..3ae34bed 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -3932,7 +3932,7 @@ (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -4134,7 +4134,7 @@ (i32.const -1) (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) diff --git a/benchmarks/pldi2026/btree/BTree.wast b/benchmarks/pldi2026/btree/BTree.wast index 86ddc11b..d2de79bf 100644 --- a/benchmarks/pldi2026/btree/BTree.wast +++ b/benchmarks/pldi2026/btree/BTree.wast @@ -3865,7 +3865,7 @@ (call $btreeInsert) (local.set 0) - (print_btree) + ;; (print_btree) ;; search for variables & check that they were inserted (local.get 0) @@ -4063,7 +4063,7 @@ (i32.eq) - (print_btree) + ;; (print_btree) (i32.and) (i32.and) From 4d8241a972fa0513bdb094c6d00770093f23810a Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:50:28 -0400 Subject: [PATCH 62/82] replace (sym_assert) with (call $i32.sym_assert) --- benchmarks/pldi2026/btree/2o2u.wat | 4 ++-- benchmarks/pldi2026/btree/2o3u.wat | 4 ++-- benchmarks/pldi2026/btree/3o1u.wat | 4 ++-- benchmarks/pldi2026/btree/3o2u.wat | 4 ++-- benchmarks/pldi2026/btree/3o3u.wat | 4 ++-- benchmarks/pldi2026/btree/4o1u.wat | 4 ++-- benchmarks/pldi2026/btree/4o2u.wat | 4 ++-- benchmarks/pldi2026/btree/4o3u.wat | 4 ++-- benchmarks/pldi2026/btree/5o1u.wat | 4 ++-- benchmarks/pldi2026/btree/5o2u.wat | 4 ++-- benchmarks/pldi2026/btree/5o3u.wat | 4 ++-- benchmarks/pldi2026/btree/6o1u.wat | 4 ++-- benchmarks/pldi2026/btree/6o2u.wat | 4 ++-- benchmarks/pldi2026/btree/6o3u.wat | 4 ++-- benchmarks/pldi2026/btree/7o1u.wat | 4 ++-- benchmarks/pldi2026/btree/7o2u.wat | 4 ++-- benchmarks/pldi2026/btree/7o3u.wat | 4 ++-- benchmarks/pldi2026/btree/8o1u.wat | 4 ++-- benchmarks/pldi2026/btree/8o2u.wat | 4 ++-- benchmarks/pldi2026/btree/9o1u.wat | 4 ++-- benchmarks/pldi2026/btree/9o2u.wat | 4 ++-- benchmarks/pldi2026/btree/BTree.wast | 4 ++-- 22 files changed, 44 insertions(+), 44 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 579fffd9..5f11614a 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3645,7 +3645,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3690,7 +3690,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index 24540db9..29ac9c04 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3678,7 +3678,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3736,7 +3736,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index 20905c9a..f42ceec9 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3650,7 +3650,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3694,7 +3694,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index 8f33dccf..80a840cd 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3682,7 +3682,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3740,7 +3740,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 06398244..d015b60c 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3720,7 +3720,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3791,7 +3791,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 040e9282..98c3177a 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3686,7 +3686,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3743,7 +3743,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 570c68cf..fb88315d 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3723,7 +3723,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3794,7 +3794,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 4d32a327..71c31067 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3766,7 +3766,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3850,7 +3850,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 457043e3..8011c3e8 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3729,7 +3729,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3799,7 +3799,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index a1e4bade..06beabf1 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3771,7 +3771,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3854,7 +3854,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 0c4efe00..0e6cdae3 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3818,7 +3818,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3914,7 +3914,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index c2280ddf..099de296 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3777,7 +3777,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3860,7 +3860,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 77712bc1..26958a81 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3824,7 +3824,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3920,7 +3920,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 67f7abc6..81385b3f 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3876,7 +3876,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3985,7 +3985,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 65d91bfe..a353d9f4 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3828,7 +3828,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3925,7 +3925,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 97f96b66..a022707d 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3881,7 +3881,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3991,7 +3991,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 2ed4b70c..30789824 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -3938,7 +3938,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -4061,7 +4061,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index eb24fdf7..0ac6f6ff 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3886,7 +3886,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -3995,7 +3995,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index 4e39fe76..9d5987f8 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -3933,7 +3933,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -4055,7 +4055,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index 647fecc2..ad182c5f 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -3949,7 +3949,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -4071,7 +4071,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 3ae34bed..24fb5f42 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -4011,7 +4011,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -4146,7 +4146,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ) (export "main" (func $main)) (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") diff --git a/benchmarks/pldi2026/btree/BTree.wast b/benchmarks/pldi2026/btree/BTree.wast index d2de79bf..2fd20603 100644 --- a/benchmarks/pldi2026/btree/BTree.wast +++ b/benchmarks/pldi2026/btree/BTree.wast @@ -3939,7 +3939,7 @@ (i32.and) (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) ;; delete & check that it was deleted ;; a @@ -4069,7 +4069,7 @@ (i32.and) (i32.and) - (sym_assert) + (call $i32.sym_assert) From 25cb4f2183964c3dcd542943270c22f4ddb22fa4 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:51:00 -0400 Subject: [PATCH 63/82] replace the usage of get_sym_int32 --- benchmarks/pldi2026/btree/2o2u.wat | 72 +++-- benchmarks/pldi2026/btree/2o3u.wat | 102 ++++--- benchmarks/pldi2026/btree/3o1u.wat | 78 +++-- benchmarks/pldi2026/btree/3o2u.wat | 111 ++++--- benchmarks/pldi2026/btree/3o3u.wat | 150 ++++++--- benchmarks/pldi2026/btree/4o1u.wat | 117 ++++--- benchmarks/pldi2026/btree/4o2u.wat | 156 ++++++---- benchmarks/pldi2026/btree/4o3u.wat | 201 ++++++++---- benchmarks/pldi2026/btree/5o1u.wat | 162 ++++++---- benchmarks/pldi2026/btree/5o2u.wat | 207 ++++++++----- benchmarks/pldi2026/btree/5o3u.wat | 258 ++++++++++------ benchmarks/pldi2026/btree/6o1u.wat | 213 ++++++++----- benchmarks/pldi2026/btree/6o2u.wat | 264 ++++++++++------ benchmarks/pldi2026/btree/6o3u.wat | 321 +++++++++++++------- benchmarks/pldi2026/btree/7o1u.wat | 270 +++++++++++------ benchmarks/pldi2026/btree/7o2u.wat | 327 +++++++++++++------- benchmarks/pldi2026/btree/7o3u.wat | 390 ++++++++++++++++-------- benchmarks/pldi2026/btree/8o1u.wat | 333 +++++++++++++------- benchmarks/pldi2026/btree/8o2u.wat | 390 ++++++++++++++++-------- benchmarks/pldi2026/btree/9o1u.wat | 402 ++++++++++++++++-------- benchmarks/pldi2026/btree/9o2u.wat | 471 +++++++++++++++++++---------- 21 files changed, 3330 insertions(+), 1665 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 5f11614a..77c0e6a1 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -3561,8 +3561,10 @@ (i32.ne) ;; logical order: a>b - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) @@ -3572,25 +3574,33 @@ ;; h (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) (i32.and) @@ -3601,16 +3611,20 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3618,25 +3632,29 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3650,36 +3668,42 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat index 29ac9c04..f3d73e19 100644 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ b/benchmarks/pldi2026/btree/2o3u.wat @@ -3561,8 +3561,10 @@ (i32.ne) ;; logical order: a>b - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) @@ -3575,41 +3577,55 @@ (sym_int32 "a") (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; j (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) @@ -3625,19 +3641,24 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3645,31 +3666,36 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3683,48 +3709,56 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index f42ceec9..f4677125 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -3563,20 +3563,27 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) @@ -3589,15 +3596,20 @@ ;; h (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) @@ -3607,16 +3619,20 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3624,25 +3640,29 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3655,36 +3675,42 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index 80a840cd..c83ef8cf 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -3563,20 +3563,27 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) @@ -3589,33 +3596,45 @@ ;; h (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) @@ -3629,19 +3648,24 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3649,31 +3673,36 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3687,48 +3716,56 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index d015b60c..95267b18 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -3563,21 +3563,28 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) (i32.and) @@ -3589,56 +3596,77 @@ ;; h (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; j (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) @@ -3657,22 +3685,28 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3680,37 +3714,43 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3725,60 +3765,70 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 98c3177a..1b1043a9 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -3563,38 +3563,52 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) (i32.and) @@ -3610,19 +3624,26 @@ ;; h (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) @@ -3633,19 +3654,24 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3653,31 +3679,36 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3691,48 +3722,56 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index fb88315d..44c5f554 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -3563,38 +3563,52 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) (i32.and) @@ -3610,41 +3624,57 @@ ;; h (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) @@ -3660,22 +3690,28 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3683,37 +3719,43 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3728,60 +3770,70 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 71c31067..2f88a00b 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -3563,38 +3563,52 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) (i32.and) @@ -3610,68 +3624,95 @@ ;; h (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; j (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) @@ -3693,25 +3734,32 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3719,43 +3767,50 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3771,72 +3826,84 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 8011c3e8..7cc60d18 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -3563,60 +3563,83 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) @@ -3638,23 +3661,32 @@ ;; h (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) @@ -3666,22 +3698,28 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3689,37 +3727,43 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3734,60 +3778,70 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 06beabf1..bc619abd 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -3563,60 +3563,83 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) @@ -3638,49 +3661,69 @@ ;; h (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) @@ -3698,25 +3741,32 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3724,43 +3774,50 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3776,72 +3833,84 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 0e6cdae3..638f7311 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -3563,60 +3563,83 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) @@ -3638,79 +3661,112 @@ ;; h (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; j (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) @@ -3735,28 +3791,36 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3764,49 +3828,57 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3823,84 +3895,98 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index 099de296..ba2db537 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -3563,87 +3563,121 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) @@ -3672,27 +3706,38 @@ ;; h (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) (i32.and) @@ -3704,25 +3749,32 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3730,43 +3782,50 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3782,72 +3841,84 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 26958a81..e8e18559 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -3563,87 +3563,121 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) @@ -3672,57 +3706,81 @@ ;; h (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) (i32.and) @@ -3741,28 +3799,36 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3770,49 +3836,57 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3829,84 +3903,98 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 81385b3f..960e001d 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -3563,87 +3563,121 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) @@ -3672,91 +3706,130 @@ ;; h (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1040) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "c") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "d") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "e") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "f") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) (i32.and) @@ -3783,31 +3856,40 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1040) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3815,55 +3897,64 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3881,96 +3972,112 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index a353d9f4..59100ae3 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -3563,116 +3563,163 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) @@ -3707,31 +3754,44 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) @@ -3745,28 +3805,36 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3774,49 +3842,57 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3833,84 +3909,98 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index a022707d..a81d8968 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -3563,116 +3563,163 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) @@ -3707,66 +3754,94 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1040) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "g") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) @@ -3788,31 +3863,40 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3820,55 +3904,64 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3886,96 +3979,112 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 30789824..7a8e06f2 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -3563,116 +3563,163 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) @@ -3707,104 +3754,149 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1040) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "g") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1042) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "b") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "c") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "d") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "e") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "f") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "g") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "h") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "j") - (get_sym_int32 "i") + (i32.const 1042) + (call $i32.symbolic) + (i32.const 1040) + (call $i32.symbolic) (i32.ne) @@ -3835,34 +3927,44 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "j") + (i32.const 1042) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3870,61 +3972,71 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "j") + (i32.const 1042) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3943,108 +4055,126 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; i (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 0ac6f6ff..266329c2 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -3563,150 +3563,212 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; x (i32.const 1044) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "b") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "c") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "d") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "e") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "f") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "g") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g>x - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "g") - (get_sym_int32 "x") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.gt_s) @@ -3749,35 +3811,50 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "x") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) @@ -3792,31 +3869,40 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3825,55 +3911,64 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3891,96 +3986,112 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; x (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat index 9d5987f8..87bd74d3 100644 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ b/benchmarks/pldi2026/btree/8o2u.wat @@ -3560,145 +3560,207 @@ ;;c (sym_int32 "c") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (sym_int32 "d") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (sym_int32 "e") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (sym_int32 "f") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (sym_int32 "g") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; x (sym_int32 "x") - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "b") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "c") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "d") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "e") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "f") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "g") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g>x - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "g") - (get_sym_int32 "x") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.gt_s) @@ -3743,32 +3805,46 @@ (sym_int32 "a") (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "x") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) ;; i @@ -3776,36 +3852,52 @@ (sym_int32 "a") (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "g") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "x") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) @@ -3829,34 +3921,44 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3865,61 +3967,71 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3938,108 +4050,126 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; x (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index ad182c5f..0202feeb 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -3563,188 +3563,267 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; x (i32.const 1044) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "b") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "c") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "d") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "e") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "f") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "g") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; y (i32.const 1046) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "b") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "c") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "d") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "e") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "f") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "g") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "x") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g>x>y - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "g") - (get_sym_int32 "x") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "x") - (get_sym_int32 "y") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1046) + (call $i32.symbolic) (i32.gt_s) @@ -3796,39 +3875,56 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "x") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "y") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1046) + (call $i32.symbolic) (i32.ne) @@ -3845,34 +3941,44 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3881,61 +3987,71 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -3954,108 +4070,126 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; x (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; y (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index 24fb5f42..c33af095 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -3563,188 +3563,267 @@ ;;c (i32.const 1028) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "c") - (get_sym_int32 "b") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) ;;d (i32.const 1030) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "b") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "d") - (get_sym_int32 "c") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) ;;e (i32.const 1032) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "b") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "c") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "e") - (get_sym_int32 "d") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) ;; f (i32.const 1034) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "b") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "c") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "d") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "f") - (get_sym_int32 "e") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) ;; g (i32.const 1036) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "b") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "c") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "d") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "e") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "g") - (get_sym_int32 "f") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) ;; x (i32.const 1044) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "b") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "c") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "d") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "e") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "f") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "x") - (get_sym_int32 "g") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) ;; y (i32.const 1046) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "b") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "c") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "d") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "e") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "f") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "g") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "y") - (get_sym_int32 "x") + (i32.const 1046) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) ;; logical order: a>b>c>d>e>f>g>x>y - (get_sym_int32 "a") - (get_sym_int32 "b") + (i32.const 1024) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "b") - (get_sym_int32 "c") + (i32.const 1026) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "c") - (get_sym_int32 "d") + (i32.const 1028) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "d") - (get_sym_int32 "e") + (i32.const 1030) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "e") - (get_sym_int32 "f") + (i32.const 1032) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "f") - (get_sym_int32 "g") + (i32.const 1034) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "g") - (get_sym_int32 "x") + (i32.const 1036) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.gt_s) - (get_sym_int32 "x") - (get_sym_int32 "y") + (i32.const 1044) + (call $i32.symbolic) + (i32.const 1046) + (call $i32.symbolic) (i32.gt_s) @@ -3796,81 +3875,117 @@ ;; h (i32.const 1038) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "b") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "c") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "d") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "e") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "f") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "g") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "x") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "h") - (get_sym_int32 "y") + (i32.const 1038) + (call $i32.symbolic) + (i32.const 1046) + (call $i32.symbolic) (i32.ne) ;; i (i32.const 1040) (call $i32.symbolic) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "b") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1026) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "c") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1028) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "d") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1030) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "e") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1032) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "f") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1034) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "g") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1036) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "x") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1044) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "y") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1046) + (call $i32.symbolic) (i32.ne) - (get_sym_int32 "i") - (get_sym_int32 "h") + (i32.const 1040) + (call $i32.symbolic) + (i32.const 1038) + (call $i32.symbolic) (i32.ne) @@ -3897,37 +4012,48 @@ (call $i32.sym_assume) ;; insert variables - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeInsert) (local.set 0) @@ -3936,67 +4062,78 @@ ;; search for variables & check that they were inserted (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) (local.get 0) - (get_sym_int32 "i") + (i32.const 1040) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.ne) @@ -4016,120 +4153,140 @@ ;; delete & check that it was deleted ;; a (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "a") + (i32.const 1024) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; b (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "b") + (i32.const 1026) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; c (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "c") + (i32.const 1028) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; d (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "d") + (i32.const 1030) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; e (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "e") + (i32.const 1032) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; f (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "f") + (i32.const 1034) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; g (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "g") + (i32.const 1036) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; x (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "x") + (i32.const 1044) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; y (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "y") + (i32.const 1046) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) ;; h (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeDelete) (local.set 0) (local.get 0) - (get_sym_int32 "h") + (i32.const 1038) + (call $i32.symbolic) (call $btreeSearch) (i32.const -1) (i32.eq) From 18e0b6bff1752861e470f55e65b0059249d1b4ba Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:55:28 -0400 Subject: [PATCH 64/82] remove two files that are not runable by wasp --- benchmarks/pldi2026/btree/2o3u.wat | 3781 ------------------------- benchmarks/pldi2026/btree/8o2u.wat | 4196 ---------------------------- 2 files changed, 7977 deletions(-) delete mode 100644 benchmarks/pldi2026/btree/2o3u.wat delete mode 100644 benchmarks/pldi2026/btree/8o2u.wat diff --git a/benchmarks/pldi2026/btree/2o3u.wat b/benchmarks/pldi2026/btree/2o3u.wat deleted file mode 100644 index f3d73e19..00000000 --- a/benchmarks/pldi2026/btree/2o3u.wat +++ /dev/null @@ -1,3781 +0,0 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 2 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1028) - (call $i32.symbolic) - (sym_int32 "a") - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - - ;; j - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00h\00i\00j\00") -) - diff --git a/benchmarks/pldi2026/btree/8o2u.wat b/benchmarks/pldi2026/btree/8o2u.wat deleted file mode 100644 index 87bd74d3..00000000 --- a/benchmarks/pldi2026/btree/8o2u.wat +++ /dev/null @@ -1,4196 +0,0 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (sym_int32 "a") - (sym_int32 "b") - (i32.ne) - - ;;c - (sym_int32 "c") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (sym_int32 "d") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (sym_int32 "e") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (sym_int32 "f") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (sym_int32 "g") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; x - (sym_int32 "x") - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g>x - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (sym_int32 "h") - (sym_int32 "a") - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - ;; i - (sym_int32 "i") - (sym_int32 "a") - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; x - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") -) - From 7968700fa91c31dd9d20cfa4161a7435b3e698da Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 21:57:08 -0400 Subject: [PATCH 65/82] convert all wat file to a form we can parse via (wasm2wat . wat2wasm) --- benchmarks/pldi2026/btree/2o1u.wat | 6332 ++++++++++------------- benchmarks/pldi2026/btree/2o2u.wat | 6421 ++++++++++-------------- benchmarks/pldi2026/btree/3o1u.wat | 6433 ++++++++++-------------- benchmarks/pldi2026/btree/3o2u.wat | 6537 ++++++++++-------------- benchmarks/pldi2026/btree/3o3u.wat | 6654 +++++++++++------------- benchmarks/pldi2026/btree/4o1u.wat | 6548 ++++++++++-------------- benchmarks/pldi2026/btree/4o2u.wat | 6665 +++++++++++------------- benchmarks/pldi2026/btree/4o3u.wat | 6795 +++++++++++-------------- benchmarks/pldi2026/btree/5o1u.wat | 6676 +++++++++++-------------- benchmarks/pldi2026/btree/5o2u.wat | 6807 +++++++++++-------------- benchmarks/pldi2026/btree/5o3u.wat | 6946 +++++++++++-------------- benchmarks/pldi2026/btree/6o1u.wat | 6818 +++++++++++-------------- benchmarks/pldi2026/btree/6o2u.wat | 6961 +++++++++++--------------- benchmarks/pldi2026/btree/6o3u.wat | 7116 +++++++++++--------------- benchmarks/pldi2026/btree/7o1u.wat | 6973 +++++++++++--------------- benchmarks/pldi2026/btree/7o2u.wat | 7129 +++++++++++--------------- benchmarks/pldi2026/btree/7o3u.wat | 7300 ++++++++++++--------------- benchmarks/pldi2026/btree/8o1u.wat | 7141 +++++++++++--------------- benchmarks/pldi2026/btree/9o1u.wat | 7323 ++++++++++++--------------- benchmarks/pldi2026/btree/9o2u.wat | 7504 ++++++++++++---------------- 20 files changed, 57896 insertions(+), 79183 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o1u.wat b/benchmarks/pldi2026/btree/2o1u.wat index 40df604c..99f62816 100644 --- a/benchmarks/pldi2026/btree/2o1u.wat +++ b/benchmarks/pldi2026/btree/2o1u.wat @@ -1,3677 +1,2655 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 2 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.and) - - ;; 1 symbolic variable w/o order - ;; h - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - ;; (print_stack) - (i32.const -1) - (i32.eq) - ;; (print_stack) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - ;; (print_stack) - (i32.const -1) - (i32.eq) - ;; (print_stack) - - - ;; ;; (print_btree) - - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00h\00")) +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.and + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00h\00")) diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 77c0e6a1..9922fcc4 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -1,3725 +1,2696 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 2 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00h\00i\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.and + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00h\00i\00")) diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index f4677125..5f8232df 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -1,3731 +1,2702 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 3 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variable w/o order - ;; h - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index c83ef8cf..ec97e590 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -1,3788 +1,2749 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 3 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 95267b18..60d0483b 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -1,3852 +1,2802 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 3 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - - ;; logical order: a>b>c - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 3 symbolic variables w/o order - ;; h - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - - ;; j - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 1b1043a9..6dfc71a3 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -1,3793 +1,2755 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 4 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variables w/o order - ;; h - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 44c5f554..4beac7a4 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -1,3857 +1,2808 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 4 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 2f88a00b..1fac0984 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -1,3928 +1,2867 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 4 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - ;; j - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 7cc60d18..1ef41296 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -1,3862 +1,2814 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variable w/o order - ;; h - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index bc619abd..432244e3 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -1,3934 +1,2873 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variable w/o order - ;; h - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 638f7311..05889194 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -1,4008 +1,2938 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 3 symbolic variable w/o order - ;; h - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; j - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index ba2db537..7302e350 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -1,3939 +1,2879 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 6 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - ;; logical order: a>b>c>d>e>f - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - - ;; 1 symbolic variables w/o order - ;; h - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index e8e18559..8c22aa9c 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -1,4017 +1,2944 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 6 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - ;; logical order: a>b>c>d>e>f - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index 960e001d..ee7d08bb 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -1,4101 +1,3015 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 6 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - - ;; logical order: a>b>c>d>e>f - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - - ;; 3 symbolic variables w/o order - ;; h - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1038 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + i32.const 1040 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1040 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1038 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 59100ae3..576560fe 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -1,4023 +1,2950 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index a81d8968..d8c85450 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -1,4108 +1,3021 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - - ;; i - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1038 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + i32.const 1040 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1040 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1038 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 7a8e06f2..0f7fd87a 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -1,4202 +1,3098 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 3 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - - ;; i - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1042) - (call $i32.symbolic) - (i32.const 1040) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1042) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1042) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; i - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - - - - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1038 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1038 + call 0 + i32.ne + i32.const 1042 + call 0 + i32.const 1040 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + i32.const 1040 + call 0 + call 8 + local.set 0 + i32.const 1042 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1040 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1042 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1038 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1040 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1040 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00")) diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 266329c2..9f76c0a1 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -1,4114 +1,3027 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; x - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g>x - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; x - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.const 1036 + call 0 + i32.const 1044 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1044 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1044 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00")) diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index 0202feeb..8686ccde 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -1,4213 +1,3110 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 5 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; x - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - ;; y - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g>x>y - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1046) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 1 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1046) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; x - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; y - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.const 1036 + call 0 + i32.const 1044 + call 0 + i32.gt_s + i32.const 1044 + call 0 + i32.const 1046 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1046 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1044 + call 0 + call 8 + local.set 0 + i32.const 1046 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1046 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1044 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1046 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1046 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00")) diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index c33af095..fff6815d 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -1,4311 +1,3193 @@ -(module - (import "i32" "symbolic" (func $i32.symbolic (param i32) (result i32))) - - (import "i32" "sym_assume" (func $i32.sym_assume (param i32))) - - (import "i32" "sym_assert" (func $i32.sym_assert (param i32))) - - (import "sym" "get_sym_int32" (func $get_sym_int32 (param i32) (result i32))) - (memory $0 1) - - - (func $createBtree (param i32) (result i32) ;; createBtree(t), where t: degree of the btree - (i32.const 0) - (local.get 0) - (i32.store) ;; store t at address 0 - - (i32.const 0) - (i32.const 1) - (i32.store offset=4) ;; store the number of nodes in the btree = 1 - - (i32.const 0) - (i32.const 65536) - (i32.store offset=8) ;; store the root addr - - (i32.const 1) ;; Now create root - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then - (i32.const 65536) ;; 64KiB = 65536 bytes - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - - (i32.const 65536) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - ) - ) - (i32.const 65536) ;; returns the address of the root - ) - - ;; btreeSearch(x, k), where x: node address; k: key to search. Returns address of the key or -1 if key is not in tree. - (func $btreeSearch (param i32) (param i32) (result i32) (local i32) - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n -1 - (i32.le_s) ;; i <= x.children-1 - (if - (then - (local.get 1) ;; k - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - (if - (then - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) ;; i - - (local.get 0) ;; x - (i32.load offset=4) ;; x.children - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.le_s) ;; i <= x.children - 1 - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.eq) - ;; k == x.keys[i] - (if (result i32) - (then - - (local.get 0) ;; save the address, which is x+8+i*4 - (i32.const 8) - (i32.add) ;; x+8 - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x+8+i*4 - - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - (else - (local.get 0) ;; x - (i32.load) ;; x is leaf? - (i32.const 1) ;; if == 1, then yes - (i32.eq) - (if (result i32) - (then - (i32.const -1) - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i - - (local.get 1) ;; k - - (call $btreeSearch) ;; btreeSearch(x.children[i], k) - - ) - ) - ) - ) - ) - - ;; btreeSplitChild(x, i), where x: addr of a non full internal node; i: index such that x.children[i] is a full child of x - (func $btreeSplitChild (param i32) (param i32) (local i32) (local i32) - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if ;; if we can grow memory - (then ;; get the number of nodes in the tree - (i32.const 0) - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address is 64KiB*(number of nodes+1) - (local.set 2) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - - (i32.load offset=8) ;; load the addr of the child in index i : y - - - (i32.load) ;; check if x.children[i] is leaf ;; load the first i32 in the child - (i32.const 1) - (i32.eq) ;; is y leaf? - (if - (then ;; yes - (local.get 2) ;; addr of new node z - (i32.const 1) - (i32.store) ;; store 1(TRUE) regarding if node is leaf - ) - (else ;; no - (local.get 2) ;; addr of new node z - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - ) - ) - - (local.get 2) ;; now store number of children, which will be t/2 -1 ;; addr of z - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - - (i32.store offset=4) ;; store number of children = (t/2)-1 - - (i32.const 0) ;; now to store the keys - (local.set 3) ;; counter = 0 - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.const 1) - (i32.sub) ;; (t/2)-1 - (i32.eq) ;; counter == (t/2)-1 - (if - (then - - (br $loop_break) - ) - (else - - (local.get 2) ;; addr of z ;; we will store in the new node's address. z.keys[counter] - - (i32.const 4) - (local.get 3) ;; counter - - (i32.mul) ;; counter * 4 - - (i32.add) ;; addr + counter * 4 -> where the key is goint to be located - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 4) ;; now get x.children[i].keys[counter+(t/2)] - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.add) ;; counter + (t/2) - - (i32.mul) ;; counter + (t/2) *4 - - (i32.add) ;; y + counter + (t/2) *4 - (i32.load offset=8) ;; y.keys[counter + (t/2)] - - (i32.store offset=8) ;; z.keys[counter] = y.keys[counter + (t/2)] - - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - - ) - ) - ) - ) - - (i32.const 0) - (local.set 3) ;; set counter back to 0 - - (i32.const 0) ;; check if x.children[i] is leaf - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + i*4 - (i32.load offset=8) ;; load the address of the child in index i = y - (i32.load) ;; get first i32 in child --> isLeaf - (i32.const 1) - (i32.ne) ;; is leaf? - - (if - (then ;; not leaf so we have to update the children - (block $loop_break - (loop $loop - - (local.get 3) ;; counter - - (i32.const 0) - (i32.load) ;; t - - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.eq) ;; counter == (t/2) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; now get z.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; counter*4 - - (i32.add) ;; (t-1)*4 + counter*4 - - (local.get 2) ;; z - (i32.add) ;; z + (t-1)*4 + counter*4 --> address where addr of child is stored - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) ;; get x.children[i].children[counter+(t/2)] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.add) ;; counter + t/2 - (i32.const 4) - (i32.mul) ;; counter+t/2 * 4 - - (i32.add) ;; (t-1)*4 + (counter+(t/2))*4 - - (i32.add) ;; x.children[i] + (t-1)*4 + (counter + (t/2))*4 - (i32.load offset=8) ;; load the address of the child in index counter + t/2 - - (i32.store offset=8) ;; z.children[counter] = x.children[i].children[counter] - - (local.get 3) ;; increment counter - (i32.const 1) - (i32.add) - (local.set 3) - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.store offset=4) ;; number of keys of x.children[i] is now t/2 -1 - - (local.get 0) ;; x - - (i32.load offset=4) ;; get x.n - (local.set 3) ;; counter = x.n - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (local.get 3) ;; counter - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; get x.children[counter + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (i32.add) ;; (t-1)*4 + (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter + 1)*4 -->address where addr of child is stored - - (i32.const 0) ;; get x.children[counter] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (i32.add) ;; (t-1)*4 + (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (counter)*4 - (i32.load offset=8) ;; load the addr of the child in index (counter) - - (i32.store offset=8) ;; x.children[counter+1] = x.children[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (i32.const 0) ;; get x.children[i + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 1) - (i32.add) ;; i + 1 - (i32.const 4) - (i32.mul) ;; (i + 1)*4 - - (i32.add) ;; (t-1)*4 + (i + 1)*4 - - (local.get 0) ;; x - - (i32.add) ;; x + (t-1)*4 + (i + 1)*4 --> addr where we will store the new addr of the child - - (local.get 2) ;; addr of z - (i32.store offset=8) ;; x.children[i+1] = z - - (local.get 0) ;; x - (i32.load offset=4) ;; get x.n - (i32.const 1) - (i32.sub) - (local.set 3) ;; counter = x.n -1 - - (block $loop_break - (loop $loop - (local.get 1) ;; i - (i32.const 1) - (i32.sub) ;; i-1 - (local.get 3) ;; counter - (i32.eq) ;; counter == i-1 - - (if - (then - (br $loop_break) - ) - (else - - (local.get 3) ;; get x.keys[counter + 1] ;; counter - (i32.const 1) - (i32.add) ;; counter + 1 - (i32.const 4) - (i32.mul) ;; (counter + 1)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter + 1)*4 --> addr where we will store the new key - - (local.get 3) ;; counter - (i32.const 4) - (i32.mul) ;; (counter)*4 - - (local.get 0) ;; x - (i32.add) ;; x +(counter)*4 - (i32.load offset=8) ;; load the key in index (counter) - - (i32.store offset=8) ;; x.keys[counter+1] = x.keys[counter] - - (local.get 3) ;; decrement counter - (i32.const 1) - (i32.sub) - (local.set 3) - (br $loop) - ) - ) - - ) - ) - - (local.get 1) ;; get x.keys[i] - (i32.const 4) - (i32.mul) ;; i*4 - - (local.get 0) ;; x - (i32.add) ;; x +i*4 --> addr of the key - - (i32.const 0) ;; get x.children[i].keys[t/2] - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; t/2 -1 - - (i32.const 4) - (i32.mul) ;; (t/2)-1 *4 - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 1) ;; i - (i32.const 4) - (i32.mul) ;; (i)*4 - - (i32.add) ;; (t-1)*4 + (i)*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 + (i)*4 - (i32.load offset=8) ;; load the address of the child in index (i) - - (i32.add) ;; y + (t/2)-1 *4 - (i32.load offset=8) ;; load the key in index (t/2)-1 from node x.children[i] - - (i32.store offset=8) ;; store the new key in the addr - - (local.get 0) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) ;; x.n + 1 - (i32.store offset=4) ;; x.n = x.n + 1 - ) - ) - ) - - ;; btreeInsertNonFull(x, k), where x: addr of a non full internal node; k: the key to insert - (func $btreeInsertNonFull (param i32) (param i32) (local i32) - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.const 1) - (i32.sub) ;; x.n -1 - (local.set 2) ;; i = x.n -1 - - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (block $loop_break - (loop $loop - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - - (if (result i32) - (then - (local.get 1) ;; k - (local.get 0) ;; x - ;; x+4*i - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - (i32.lt_s) ;; k < x.keys[i] - ) - (else - (i32.const 0) - ) - ) - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i <= 0? - (i32.and) - - (if - (then - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i *4 - - (i32.add) ;; x + i *4 --> addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.keys[i+1] = x.keys[i] - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 2) ;; i = i-1 - (br $loop) - - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.mul) ;; i+1 *4 - - (i32.add) ;; x + i+1 *4 --> addr of x.keys[i+1] - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.keys[i+1] = k - - (local.get 0) - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;; x.n = x.n +1 - - ) - (else ;; x is not leaf - (block $loop_break - (loop $loop - - (local.get 2) ;; i - (i32.const 0) - (i32.ge_s) ;; i >= 0 - - (if - (then - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.lt_s) ;; k < x.keys[i] - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i -1 - (local.set 2) ;; i = i-1 - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - - (i32.const 1) - (i32.add) - - (local.set 2) ;;i = i+1 - - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address of the child in index i = y - (i32.load offset=8) ;; load the address of the child in index i = y - - (i32.load offset=4) ;; get y.n - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; y.n == t-1 --> node is full - (if - (then - (local.get 0) ;; x - - (local.get 2) ;; i - (call $btreeSplitChild) - - (local.get 1) ;; k - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k>x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i+1 - ) - ) - ) - ) - - (i32.const 0) ;; get x.children[i] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; load the address of the child in index i = y - - (local.get 1) ;; k - - (call $btreeInsertNonFull) - - ) - ) - ) - - (func $btreeInsert (param i32) (result i32) (local i32) (local i32) - (i32.const 0) - (i32.load offset=8) ;; root addr - (local.tee 2) ;; set r - - (i32.load offset=4) ;; r.n - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.eq) ;; r.n == t-1 --> root is full - (if (result i32) - (then - - (i32.const 1) ;; create a new node - (memory.grow) ;; create new page - (i32.const -1) - (i32.ne) - (if (result i32) ;; if we can grow memory - (then - (i32.const 0) ;; get the number of nodes in the tree - (i32.load offset=4) ;; number of nodes in the tree - (i32.const 1) - (i32.add) ;; number of nodes + 1 - (i32.const 65536) - (i32.mul) ;; address of s is 64KiB*(number of nodes+1) - (local.set 1) - - (i32.const 0) ;; change number of nodes - (i32.const 0) - (i32.load offset=4) - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; set number of nodes to + 1 - - (i32.const 0) - (local.get 1) ;; s - (i32.store offset=8) ;; root addr is now s - - (local.get 1) ;; s - (i32.const 0) - (i32.store) ;; store 0(FALSE) regarding if node is leaf - - (local.get 1) ;; now store number of keys - (i32.const 0) - (i32.store offset=4) ;; store number of keys = 0 - - (i32.const 0) ;; store children addresses - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 1) ;; x - (i32.add) ;; x + (t-1)*4 --> addre where addr of child number 0 is located - (local.get 2) - - (i32.store offset=8) ;; s.children[0] = r - - (local.get 1) ;; s - (i32.const 0) - - (call $btreeSplitChild) - - (local.get 1) ;; s - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 1) ;; return the address of the new root - ) - (else - (i32.const -1) ;; return -1 because we could not create a new node - ) - ) - ) - (else - (local.get 2) ;; r - (local.get 0) ;; k - (call $btreeInsertNonFull) - (local.get 2) ;; return the address of the root, which is the same - ) - ) - ) - - ;; Returns the address of the new root (if applicable, otherwise returns the addres of the root) - (func $btreeDelete (param i32) (param i32) (result i32) (local i32) (local i32) (local i32) (local i32) - (local.get 0) ;; x - (i32.load) ;; get first i32 --> isLeaf - (i32.const 1) - (i32.eq) ;; is leaf? - (if - (then ;; x is leaf - (i32.const 0) - (local.set 2) ;; i = 0 - (block $loop_break - (loop $loop - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (local.get 2) ;; i - - (i32.eq) ;; i == x.n - (if - (then - (br $loop_break) ;; break from loop - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - - (i32.eq) ;; k == x.keys[i] - (if - (then - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $while_break - (loop $while - (local.get 3) ;; j - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n-1 - (i32.eq) ;; j == x.n-1 - (if - (then - (br $while_break) - ) - (else - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - - (i32.add) ;; x + j*4 --> addr where x.keys[j] is stored - - (local.get 0) ;; x - - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.mul) ;; j+1 *4 - - (i32.add) ;; x + j+1 *4 --> addr where x.keys[j+1] is stored - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $while) - ) - ) - - ) - ) - (local.get 0) ;; x - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.n = x.n -1 - (br $loop_break) - ) - - ) - ) - - ) - (i32.const 1) - (local.get 2) - (i32.add) - (local.set 2) ;; i = i+1 - (br $loop) ;; continue - ) - ) - ) - (else ;; x is not leaf - - (i32.const 0) ;;get the index of the appropriate child/key - (local.set 2) ;; i = 0 - - (block $loop_break - (loop $loop - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (if (result i32) - (then - (local.get 1) ;; k - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (i32.gt_s) ;; k > x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (local.get 2) ;; i - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.le_s) ;; i <= x.n - 1 - - (i32.and) ;; i <= x.n - 1 && k > x.keys[i] - - (if - (then - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (local.set 2) ;; i = i + 1 - - (br $loop) - ) - (else - (br $loop_break) - ) - ) - ) - ) - (local.get 2) - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.lt_s) ;; i < x.n - (if (result i32) - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[i] - - (local.get 1) ;; k - (i32.eq) ;; k == x.keys[i] - ) - (else - (i32.const 0) - ) - ) - (if - (then ;; key is present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.tee 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i].n >= t/2 - (if - (then - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.sub) ;; index = x.c[i].n - 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[x.c[i].n - 1] - - (call $btreeDelete) ;; (x.c[i], x.c[i].keys[x.c[i].n - 1]) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i].keys[x.c[i].n - 1] - - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i+1] - (local.tee 5) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (local.get 5) ;; x.c[i+1] - (local.get 5) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[0] - (call $btreeDelete) - (drop) - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - ) - (else - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i *4 - (i32.add) ;; x + i*4 --> addr where x.c[i].keys[x.c[i].n] will be stored - - (local.get 1) ;; k - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = k - - (i32.const 0) ;; now merge x.c[i] with x.c[i+1] - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - (i32.add) ;; (t-1)*4 + i+1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - - (if ;; j == x.c[i+1].n - (then - (br $loop_break) - ) - (else - - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n + j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[index] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x.c[i+1] + i*4 ;; addr of x.c[i+1].keys[j] - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[index] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - - ) - - ) - ) - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n +1 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.add) - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + 1 + x.c[i+1].n - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - - (i32.const 0) ;; now adjust the children - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.get 3) ;; j - (i32.add) ;; index = x.c[i].n+j - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x.c[i] + (t-1)*4 --> address where x.c[i].c[x.c[i].n+j] is stored - - (i32.const 0) ;;get x.c[i+1].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x.c[i+1] + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - (i32.const 1) - (i32.sub) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; j*4 - (i32.add) ;; x + j*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.add) - (i32.mul) ;; j+1*4 - (i32.add) ;; x + j+1*4 ;; addr of x.keys[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - - ) - ) - - (local.get 2) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = i+1 - - (block $loop_break - (loop $loop - (local.get 0) - (i32.load offset=4) - - (local.get 3) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.add) ;; j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - (local.get 0) - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - (i32.store offset=4) ;; x.n = x.n-1 - - (local.get 5) ;; x.c[i] - (local.get 1) ;; k - - (call $btreeDelete) - (drop) - - ) - ) - - ) - ) - - ) - (else ;; key not present in node x - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 4) - (i32.mul) ;; i*4 - - (i32.add) ;; (t-1)*4 + i*4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> address where addr of child in index i is located - (i32.load offset=8) ;; x.c[i] - - (local.set 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) - (i32.const 1) - (i32.sub) ;; t/2 - 1 - - (i32.eq) - - (if - (then - (i32.const -1) - (local.set 4) ;; changed = -1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.le_s) ;; i+1 <= x.n - - (if - (then - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i+1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i+1].n >= t/2 - - (if - (then - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.const 1) - (i32.sub) ;; index = t/2 -1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[t/2-1] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[t/2-1] = x.keys[i] - - (local.get 5) - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - - (i32.store offset=4) ;;x.c[i].n = x.c[i].n +1 - - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i+1].keys[0] - (i32.load offset=8) ;; x.c[i+1].keys[0] - - (i32.store offset=8) ;; x.keys[i] = x.c[i+1].keys[0] - - (local.get 5) - (i32.load) ;; x.c[i] is leaf? - (i32.const 1) - (i32.ne) - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - - (i32.const 0) ;;get x.c[i].c[t/2] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; index = t/2 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[t/2] - - (i32.const 0) ;;get x.c[i+1].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[0] - - (i32.store offset=8) ;; x.c[i].c[t/2] = x.c[i+1].c[0] - ) - ) - - (local.get 5) ;; x.c[i] - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - (i32.store offset=4) ;; x.c[i].n = t/2 - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 --> address where x.c[i+1].keys[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j+1] - - (i32.store offset=8) ;; x.c[i+1].keys[j] = x.c[i+1].keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if ;; if x.c[i] is not leaf, we have to adjust children - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 --> address where x.c[i+1].c[j] is located - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j+1 - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j+1] - - (i32.store offset=8) ;; x.c[i+1].c[j] = x.c[i+1].c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j+1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr where x.c[i+1] is located - (i32.load offset=8) - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i+1].n = x.c[i+1].n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - (i32.const 0) - (i32.ge_s) ;; i -1 >= 0 - - (i32.and) ;; changed == -1 && i -1 >= 0 - - (if - (then - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 0) - (i32.load) ;; t - (i32.const 2) - (i32.div_s) ;; t/2 - - (i32.ge_s) ;; x.c[i-1].n >= t/2 - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (local.set 3) ;; j = x.c[i].n - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[j-1] - (i32.load offset=8) ;; x.c[i].keys[j-1] - - (i32.store offset=8) ;; x.c[i].keys[j] = x.c[i].keys[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - - (if - (then - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (local.set 3) ;; j = x.c[i].n + 1 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) - (i32.eq) - - (if - (then - (br $loop_break) - ) - (else - (i32.const 0) ;;get x.c[i].c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> address where x.c[i].c[j] is located - - (i32.const 0) ;;get x.c[i].c[j-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; j - (i32.const 1) - (i32.sub) ;; j-1 - (i32.const 4) - (i32.mul) ;; j *4 - - (i32.add) ;; (t-1)*4 + j *4 - - (local.get 5) ;; x.c[i] - (i32.add) - (i32.load offset=8) ;; x.c[i].c[j-1] - - (i32.store offset=8) ;; x.c[i].c[j] = x.c[i].c[j-1] - - (local.get 3) - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = j-1 - - (br $loop) - ) - ) - ) - ) - ) - ) - - (local.get 5) - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) - (i32.store offset=4) ;; ;; x.c[i].n = x.c[i].n + 1 - - (local.get 5) ;; x.c[i] - (i32.const 4) - (i32.const 0) ;; index = 0 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[0] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i-1] - - (i32.store offset=8) ;; x.c[i].keys[0] = x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) - (i32.load offset=4) ;; x.c[i-1].n - - (i32.const 1) - (i32.sub) - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n - 1 - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; index = i-1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - (i32.load offset=8) - - (i32.store offset=8) ;; x.keys[i-1] = x.c[i-1].keys[x.c[i-1].n] - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - - (i32.const 0) ;; get x.c[i].c[0] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 ;; addr where x.c[i].c[0] is located - - (i32.const 0) ;; get x.c[i-1].c[x.c[i-1].n + 1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (i32.const 1) - (i32.add) ;; index = x.c[i-1.n + 1] - - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1].c[x.c[i-1].n + 1] - - (i32.store offset=8) ;; x.c[i].c[0] = x.c[i-1].c[x.c[i-1].n + 1] - - ) - ) - (i32.const 0) - (local.set 4) ;; changed = 0 - ) - ) - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) - (if ;; changed == -1? - (then - - (local.get 2) ;; we have to merge x.c[i] with one sibling;; i - (i32.const 1) - (i32.add) ;; i+1 - - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - - (i32.le_s) - (if ;; i+1 <= x.n - (then - - (local.get 5) ;; merge with right sibling;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) ;; index = x.c[i].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n] = x.keys[i] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - (local.get 5) ;; x.c[i] - (i32.const 4) - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i].keys[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i+1].keys[j] - - (i32.store offset=8) ;; x.c[i].keys[x.c[i].n+j] = x.c[i+1].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i+1].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 5) - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i].c[x.c[i].n+j] - - (i32.const 0) ;;get x.c[i].c[x.c[i].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1].c[j] - - (i32.store offset=8) ;; x.c[i].c[x.c[i].n+j] = x.c[i+1].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (local.get 5) ;; x.c[i] - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.const 0) ;;get x.c[i+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i+1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i+1] - (i32.load offset=4) ;; x.c[i+1].n - - (i32.add) ;; x.c[i].n + x.c[i+1].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i].n = x.c[i].n + x.c[i+1].n + 1 - - (local.get 2) ;; i - (i32.const 1) - (i32.add) ;; i+1 - (local.set 3) ;; j = i+1 - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j+1] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - ) - ) - (local.get 2) ;; i - (local.set 3) ;; j = i - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - - (i32.const 0) - (local.set 4) ;; changed = 0 - - ) - ) - - (local.get 4) ;; changed - (i32.const -1) - (i32.eq) ;; changed == -1 ? - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) ;; i - 1 - - (i32.const 0) - (i32.ge_s) ;; i - 1 >= 0? - - (i32.and) ;; changed == -1 && i - 1 >= 0 - (if - (then - - (i32.const 0) ;; merge with left sibling ;;get x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; index = x.c[i-1].n - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n] - - (local.get 0) ;; x - (i32.const 4) - (local.get 2) ;; index = i - (i32.const 1) - (i32.sub) ;; index = i-1 - - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[i-1] - (i32.load offset=8) ;; x.keys[i] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n] = x.keys[i-1] - - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;; x.c[i-1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.const 4) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.c[i-1].keys[x.c[i-1].n+j] - - (local.get 5) ;; x.c[i] - (i32.const 4) - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.c[i].keys[j] - - (i32.store offset=8) ;; x.c[i-1].keys[x.c[i-1].n+j] = x.c[i].keys[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - - (local.get 5) - (i32.load) - (i32.const 1) - (i32.ne) - (if - (then - (i32.const 0) - (local.set 3) ;; j = 0 - - (block $loop_break - (loop $loop - (local.get 3) ;; j - - (local.get 5) ;; x.c[i] - (i32.load offset=4) ;; x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + 1 - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[i-1].c[x.c[i-1].n+j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) - (local.get 3) - (i32.add) - (i32.const 1) - (i32.add) ;; index = x.c[i-1].n+j+1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.add) ;; x + (t-1)*4 --> addr of x.c[i-1].c[x.c[i-1].n+j] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 5) ;; x.c[i] - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i].c[j] - - (i32.store offset=8) ;; x.c[i-1].c[x.c[i-1].n+j] = x.c[i].c[j] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - (br $loop) - ) - ) - - ) - ) - ) - ) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (i32.load offset=4) ;; x.c[i-1].n - - (local.get 5) - (i32.load offset=4) ;; x.c[i].n - - (i32.add) ;; x.c[i-1].n + x.c[i].n - (i32.const 1) - (i32.add) ;; x.c[i].n + x.c[i+1].n + 1 - - (i32.store offset=4) ;; x.c[i-1].n = x.c[i-1].n + x.c[i].n + 1 - - (local.get 2) ;; i - (local.set 3) ;; j = i - - (block $loop_break ;; re-organize x - (loop $loop - - (local.get 3) - - (local.get 0) - (i32.load offset=4) ;; x.n - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (i32.const 0) ;;get x.c[j] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) ;; index = j - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - - (i32.const 0) ;;get x.c[j+1] - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.const 4) - (i32.mul) ;; i-1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 --> addr of x.c[j] - (i32.load offset=8) ;; x.c[j+1] - - (i32.store offset=8) ;; x.c[j] = x.c[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (local.set 3) ;; j = i - 1 - (block $loop_break - (loop $loop - - (local.get 3) ;; j - - (local.get 0) - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) - - (i32.eq) - (if - (then - (br $loop_break) - ) - (else - - (local.get 0) ;; x - (i32.const 4) - - (local.get 3) ;; index = j - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 ;; addr of x.keys[j] - - (local.get 0) ;; x - (i32.const 4) - (local.get 3) - (i32.const 1) - (i32.add) ;; index = j + 1 - (i32.mul) ;; i*4 - (i32.add) ;; x + i*4 - (i32.load offset=8) ;; x.keys[j+1] - - (i32.store offset=8) ;; x.keys[j] = x.keys[j+1] - - (local.get 3) - (i32.const 1) - (i32.add) - (local.set 3) ;; j = j + 1 - - (br $loop) - - ) - ) - - ) - ) - (local.get 0) ;; x - (local.get 0) ;; x - (i32.load offset=4) ;; x.n - (i32.const 1) - (i32.sub) ;; x.n - 1 - (i32.store offset=4) ;; x.n = x.n - 1 - ) - ) - ) - ) - ) - ) - (local.get 4) - (i32.const -1) - (i32.eq) - (if ;; changed == -1? if yes, we merged with left sibling - (then - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (local.get 2) ;; i - (i32.const 1) - (i32.sub) - (i32.const 4) - (i32.mul) ;; i+1 *4 - - (i32.add) ;; (t-1)*4 + i-1 *4 - - (local.get 0) ;; x - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; x.c[i-1] - (local.get 1) - (call $btreeDelete) - (drop) - ) - (else - (local.get 5) ;; x.c[i] - (local.get 1) - (call $btreeDelete) - (drop) - ) - ) - - ) - ) - ) ;; end of if x is not leaf - ) - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.load offset=4) - (i32.const 0) - (i32.eq) - (if ;; if root is empty - (then - (i32.const 0) - - (i32.const 0) - (i32.load) ;; t - (i32.const 1) - (i32.sub) ;; t-1 - (i32.const 4) - (i32.mul) ;; (t-1)*4 - - (i32.const 0) ;; index = 0 - (i32.const 4) - (i32.mul) ;; i *4 - - (i32.add) ;; (t-1)*4 + i *4 - - (i32.const 0) - (i32.load offset=8) ;; root addr - (i32.add) ;; x + (t-1)*4 - (i32.load offset=8) ;; root.c[0] - - (i32.store offset=8) ;; root = root.c[0] - ) - ) - - (i32.const 0) - (i32.load offset=8) ;; root addr - ) - - - (func $main - (local i32) - (i32.const 4) ;;create a tree with degree 4 - (call $createBtree) - (local.set 0) - - ;; 9 symbolic variables w/ order - ;; a and b - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;c - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - ;;d - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - ;;e - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - ;; f - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - ;; g - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - ;; x - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - ;; y - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1046) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - ;; logical order: a>b>c>d>e>f>g>x>y - (i32.const 1024) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1026) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1028) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1030) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1032) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1034) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1036) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.gt_s) - - (i32.const 1044) - (call $i32.symbolic) - (i32.const 1046) - (call $i32.symbolic) - (i32.gt_s) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - ;; 2 symbolic variables w/o order - ;; h - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1038) - (call $i32.symbolic) - (i32.const 1046) - (call $i32.symbolic) - (i32.ne) - - ;; i - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1024) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1026) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1028) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1030) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1032) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1034) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1036) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1044) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1046) - (call $i32.symbolic) - (i32.ne) - - (i32.const 1040) - (call $i32.symbolic) - (i32.const 1038) - (call $i32.symbolic) - (i32.ne) - - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assume) - - ;; insert variables - (i32.const 1024) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeInsert) - (local.set 0) - - - ;; (print_btree) - - ;; search for variables & check that they were inserted - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (local.get 0) - (i32.const 1040) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.ne) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (call $i32.sym_assert) - - ;; delete & check that it was deleted - ;; a - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1024) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; b - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1026) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; c - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1028) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; d - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1030) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; e - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1032) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; f - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1034) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; g - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1036) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; x - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1044) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; y - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1046) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; h - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeDelete) - (local.set 0) - - (local.get 0) - (i32.const 1038) - (call $i32.symbolic) - (call $btreeSearch) - (i32.const -1) - (i32.eq) - - ;; (print_btree) - - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - (i32.and) - - (call $i32.sym_assert) - ) - (export "main" (func $main)) - (data $0 (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00") -) - +(module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32))) + (type (;4;) (func)) + (import "i32" "symbolic" (func (;0;) (type 0))) + (import "i32" "sym_assume" (func (;1;) (type 1))) + (import "i32" "sym_assert" (func (;2;) (type 1))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (func (;4;) (type 0) (param i32) (result i32) + i32.const 0 + local.get 0 + i32.store + i32.const 0 + i32.const 1 + i32.store offset=4 + i32.const 0 + i32.const 65536 + i32.store offset=8 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 65536 + i32.const 1 + i32.store + i32.const 65536 + i32.const 0 + i32.store offset=4 + end + i32.const 65536) + (func (;5;) (type 2) (param i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if ;; label = @3 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @4 + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 2 (;@2;) + else + br 3 (;@1;) + end + else + br 2 (;@1;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @1 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.eq + if (result i32) ;; label = @2 + local.get 0 + i32.const 8 + i32.add + i32.const 4 + local.get 2 + i32.mul + i32.add + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @3 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end + else + local.get 0 + i32.load + i32.const 1 + i32.eq + if (result i32) ;; label = @2 + i32.const -1 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 5 + end + end) + (func (;6;) (type 3) (param i32 i32) + (local i32 i32) + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if ;; label = @1 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.eq + if ;; label = @2 + local.get 2 + i32.const 1 + i32.store + else + local.get 2 + i32.const 0 + i32.store + end + local.get 2 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 2 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + local.set 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load + i32.const 1 + i32.ne + if ;; label = @2 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.eq + if ;; label = @5 + br 2 (;@3;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 2 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.add + i32.const 4 + i32.mul + i32.add + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.load offset=4 + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + local.get 2 + i32.store offset=8 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @2 + loop ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + local.get 0 + i32.add + local.get 3 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@3;) + end + end + end + local.get 1 + i32.const 4 + i32.mul + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 1 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + end) + (func (;7;) (type 3) (param i32 i32) + (local i32) + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.set 2 + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + else + i32.const 0 + end + local.get 2 + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.add + i32.mul + i32.add + local.get 1 + i32.store offset=8 + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + else + block ;; label = @2 + loop ;; label = @3 + local.get 2 + i32.const 0 + i32.ge_s + if ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.lt_s + if ;; label = @5 + local.get 2 + i32.const 1 + i32.sub + local.set 2 + br 2 (;@3;) + else + br 3 (;@2;) + end + else + br 2 (;@2;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if ;; label = @2 + local.get 0 + local.get 2 + call 6 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + if ;; label = @3 + local.get 2 + i32.const 1 + i32.add + local.set 2 + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 7 + end) + (func (;8;) (type 0) (param i32) (result i32) + (local i32 i32) + i32.const 0 + i32.load offset=8 + local.tee 2 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.eq + if (result i32) ;; label = @1 + i32.const 1 + memory.grow + i32.const -1 + i32.ne + if (result i32) ;; label = @2 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 65536 + i32.mul + local.set 1 + i32.const 0 + i32.const 0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + i32.const 0 + local.get 1 + i32.store offset=8 + local.get 1 + i32.const 0 + i32.store + local.get 1 + i32.const 0 + i32.store offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 1 + i32.add + local.get 2 + i32.store offset=8 + local.get 1 + i32.const 0 + call 6 + local.get 1 + local.get 0 + call 7 + local.get 1 + else + i32.const -1 + end + else + local.get 2 + local.get 0 + call 7 + local.get 2 + end) + (func (;9;) (type 2) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + local.get 0 + i32.load + i32.const 1 + i32.eq + if ;; label = @1 + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 0 + i32.load offset=4 + local.get 2 + i32.eq + if ;; label = @4 + br 2 (;@2;) + else + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + if ;; label = @5 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + br 3 (;@2;) + end + end + i32.const 1 + local.get 2 + i32.add + local.set 2 + br 0 (;@3;) + end + end + else + i32.const 0 + local.set 2 + block ;; label = @2 + loop ;; label = @3 + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + if (result i32) ;; label = @4 + local.get 1 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.gt_s + else + i32.const 0 + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.le_s + i32.and + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.set 2 + br 1 (;@3;) + else + br 2 (;@2;) + end + end + end + local.get 2 + local.get 0 + i32.load offset=4 + i32.lt_s + if (result i32) ;; label = @2 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + local.get 1 + i32.eq + else + i32.const 0 + end + if ;; label = @2 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @3 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.tee 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + local.get 5 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + call 9 + drop + i32.store offset=8 + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 1 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.store offset=4 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @5 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + end + local.get 2 + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @5 + loop ;; label = @6 + local.get 0 + i32.load offset=4 + local.get 3 + i32.eq + if ;; label = @7 + br 2 (;@5;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@6;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 5 + local.get 1 + call 9 + drop + end + end + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.set 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.eq + if ;; label = @3 + i32.const -1 + local.set 4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.const 4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 1 + i32.sub + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + local.get 5 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.store offset=4 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 2 + i32.div_s + i32.ge_s + if ;; label = @5 + local.get 5 + i32.load offset=4 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.sub + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get 5 + i32.const 4 + i32.const 0 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + local.set 4 + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @4 + local.get 2 + i32.const 1 + i32.add + local.get 0 + i32.load offset=4 + i32.le_s + if ;; label = @5 + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 5 + i32.const 4 + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 5 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + local.get 5 + local.get 5 + i32.load offset=4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + i32.const 1 + i32.add + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + i32.const 0 + local.set 4 + end + local.get 4 + i32.const -1 + i32.eq + local.get 2 + i32.const 1 + i32.sub + i32.const 0 + i32.ge_s + i32.and + if ;; label = @5 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 2 + i32.const 1 + i32.sub + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + i32.const 0 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 5 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 4 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.mul + i32.add + local.get 5 + i32.const 4 + local.get 3 + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 5 + i32.load + i32.const 1 + i32.ne + if ;; label = @6 + i32.const 0 + local.set 3 + block ;; label = @7 + loop ;; label = @8 + local.get 3 + local.get 5 + i32.load offset=4 + i32.const 1 + i32.add + i32.eq + if ;; label = @9 + br 2 (;@7;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 3 + i32.add + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 5 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@8;) + end + end + end + end + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.load offset=4 + local.get 5 + i32.load offset=4 + i32.add + i32.const 1 + i32.add + i32.store offset=4 + local.get 2 + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 3 + i32.const 1 + i32.add + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 2 + i32.const 1 + i32.sub + local.set 3 + block ;; label = @6 + loop ;; label = @7 + local.get 3 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.eq + if ;; label = @8 + br 2 (;@6;) + else + local.get 0 + i32.const 4 + local.get 3 + i32.mul + i32.add + local.get 0 + i32.const 4 + local.get 3 + i32.const 1 + i32.add + i32.mul + i32.add + i32.load offset=8 + i32.store offset=8 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@7;) + end + end + end + local.get 0 + local.get 0 + i32.load offset=4 + i32.const 1 + i32.sub + i32.store offset=4 + end + end + end + local.get 4 + i32.const -1 + i32.eq + if ;; label = @3 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + local.get 2 + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.add + local.get 0 + i32.add + i32.load offset=8 + local.get 1 + call 9 + drop + else + local.get 5 + local.get 1 + call 9 + drop + end + end + end + i32.const 0 + i32.load offset=8 + i32.load offset=4 + i32.const 0 + i32.eq + if ;; label = @1 + i32.const 0 + i32.const 0 + i32.load + i32.const 1 + i32.sub + i32.const 4 + i32.mul + i32.const 0 + i32.const 4 + i32.mul + i32.add + i32.const 0 + i32.load offset=8 + i32.add + i32.load offset=8 + i32.store offset=8 + end + i32.const 0 + i32.load offset=8) + (func (;10;) (type 4) + (local i32) + i32.const 4 + call 4 + local.set 0 + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1028 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1030 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1032 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1034 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1036 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1044 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1046 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.const 1024 + call 0 + i32.const 1026 + call 0 + i32.gt_s + i32.const 1026 + call 0 + i32.const 1028 + call 0 + i32.gt_s + i32.const 1028 + call 0 + i32.const 1030 + call 0 + i32.gt_s + i32.const 1030 + call 0 + i32.const 1032 + call 0 + i32.gt_s + i32.const 1032 + call 0 + i32.const 1034 + call 0 + i32.gt_s + i32.const 1034 + call 0 + i32.const 1036 + call 0 + i32.gt_s + i32.const 1036 + call 0 + i32.const 1044 + call 0 + i32.gt_s + i32.const 1044 + call 0 + i32.const 1046 + call 0 + i32.gt_s + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.const 1038 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.const 1038 + call 0 + i32.const 1046 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1024 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1026 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1028 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1030 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1032 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1034 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1036 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1044 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1046 + call 0 + i32.ne + i32.const 1040 + call 0 + i32.const 1038 + call 0 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 1 + i32.const 1024 + call 0 + call 8 + local.set 0 + i32.const 1026 + call 0 + call 8 + local.set 0 + i32.const 1028 + call 0 + call 8 + local.set 0 + i32.const 1030 + call 0 + call 8 + local.set 0 + i32.const 1032 + call 0 + call 8 + local.set 0 + i32.const 1034 + call 0 + call 8 + local.set 0 + i32.const 1036 + call 0 + call 8 + local.set 0 + i32.const 1044 + call 0 + call 8 + local.set 0 + i32.const 1046 + call 0 + call 8 + local.set 0 + i32.const 1038 + call 0 + call 8 + local.set 0 + i32.const 1040 + call 0 + call 8 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1046 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.ne + local.get 0 + i32.const 1040 + call 0 + call 5 + i32.const -1 + i32.ne + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2 + local.get 0 + i32.const 1024 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1024 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1026 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1026 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1028 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1028 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1030 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1030 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1032 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1032 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1034 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1034 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1036 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1036 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1044 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1044 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1046 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1046 + call 0 + call 5 + i32.const -1 + i32.eq + local.get 0 + i32.const 1038 + call 0 + call 9 + local.set 0 + local.get 0 + i32.const 1038 + call 0 + call 5 + i32.const -1 + i32.eq + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + i32.and + call 2) + (memory (;0;) 1) + (export "main" (func 10)) + (data (;0;) (i32.const 1024) "a\00b\00c\00d\00e\00f\00g\00h\00i\00j\00x\00y\00")) From f88be3b4c5a370d0100269b90ef01f0fbed74524 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 22:04:13 -0400 Subject: [PATCH 66/82] get_sym_int32 is not useful anymore --- benchmarks/pldi2026/btree/2o1u.wat | 2 +- benchmarks/pldi2026/btree/2o2u.wat | 2 +- benchmarks/pldi2026/btree/3o1u.wat | 2 +- benchmarks/pldi2026/btree/3o2u.wat | 2 +- benchmarks/pldi2026/btree/3o3u.wat | 2 +- benchmarks/pldi2026/btree/4o1u.wat | 2 +- benchmarks/pldi2026/btree/4o2u.wat | 2 +- benchmarks/pldi2026/btree/4o3u.wat | 2 +- benchmarks/pldi2026/btree/5o1u.wat | 2 +- benchmarks/pldi2026/btree/5o2u.wat | 2 +- benchmarks/pldi2026/btree/5o3u.wat | 2 +- benchmarks/pldi2026/btree/6o1u.wat | 2 +- benchmarks/pldi2026/btree/6o2u.wat | 2 +- benchmarks/pldi2026/btree/6o3u.wat | 2 +- benchmarks/pldi2026/btree/7o1u.wat | 2 +- benchmarks/pldi2026/btree/7o2u.wat | 2 +- benchmarks/pldi2026/btree/7o3u.wat | 2 +- benchmarks/pldi2026/btree/8o1u.wat | 2 +- benchmarks/pldi2026/btree/9o1u.wat | 2 +- benchmarks/pldi2026/btree/9o2u.wat | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o1u.wat b/benchmarks/pldi2026/btree/2o1u.wat index 99f62816..e23c8fe1 100644 --- a/benchmarks/pldi2026/btree/2o1u.wat +++ b/benchmarks/pldi2026/btree/2o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 9922fcc4..49f245e6 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index 5f8232df..6fd718aa 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index ec97e590..605bb81f 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index 60d0483b..b67fd27e 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index 6dfc71a3..c74466b5 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 4beac7a4..0c096699 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index 1fac0984..dc2a36e6 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 1ef41296..0a4ff684 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 432244e3..51775f0e 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index 05889194..c18b66f6 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index 7302e350..1d55287b 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 8c22aa9c..804c345f 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index ee7d08bb..b4fc26a7 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index 576560fe..e865bc50 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index d8c85450..2169d606 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 0f7fd87a..16057c8c 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 9f76c0a1..3af9992f 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index 8686ccde..e8259458 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index fff6815d..ba0affca 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - (import "sym" "get_sym_int32" (func (;3;) (type 0))) + ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 From b6056d8be41c095118f72dd70e63ddefb9debc33 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 22:34:22 -0400 Subject: [PATCH 67/82] take get_sym_int32 back but don't use them --- benchmarks/pldi2026/btree/2o1u.wat | 2 +- benchmarks/pldi2026/btree/2o2u.wat | 2 +- benchmarks/pldi2026/btree/3o1u.wat | 2 +- benchmarks/pldi2026/btree/3o2u.wat | 2 +- benchmarks/pldi2026/btree/3o3u.wat | 2 +- benchmarks/pldi2026/btree/4o1u.wat | 2 +- benchmarks/pldi2026/btree/4o2u.wat | 2 +- benchmarks/pldi2026/btree/4o3u.wat | 2 +- benchmarks/pldi2026/btree/5o1u.wat | 2 +- benchmarks/pldi2026/btree/5o2u.wat | 2 +- benchmarks/pldi2026/btree/5o3u.wat | 2 +- benchmarks/pldi2026/btree/6o1u.wat | 2 +- benchmarks/pldi2026/btree/6o2u.wat | 2 +- benchmarks/pldi2026/btree/6o3u.wat | 2 +- benchmarks/pldi2026/btree/7o1u.wat | 2 +- benchmarks/pldi2026/btree/7o2u.wat | 2 +- benchmarks/pldi2026/btree/7o3u.wat | 2 +- benchmarks/pldi2026/btree/8o1u.wat | 2 +- benchmarks/pldi2026/btree/9o1u.wat | 2 +- benchmarks/pldi2026/btree/9o2u.wat | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/benchmarks/pldi2026/btree/2o1u.wat b/benchmarks/pldi2026/btree/2o1u.wat index e23c8fe1..99f62816 100644 --- a/benchmarks/pldi2026/btree/2o1u.wat +++ b/benchmarks/pldi2026/btree/2o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/2o2u.wat b/benchmarks/pldi2026/btree/2o2u.wat index 49f245e6..9922fcc4 100644 --- a/benchmarks/pldi2026/btree/2o2u.wat +++ b/benchmarks/pldi2026/btree/2o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o1u.wat b/benchmarks/pldi2026/btree/3o1u.wat index 6fd718aa..5f8232df 100644 --- a/benchmarks/pldi2026/btree/3o1u.wat +++ b/benchmarks/pldi2026/btree/3o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o2u.wat b/benchmarks/pldi2026/btree/3o2u.wat index 605bb81f..ec97e590 100644 --- a/benchmarks/pldi2026/btree/3o2u.wat +++ b/benchmarks/pldi2026/btree/3o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/3o3u.wat b/benchmarks/pldi2026/btree/3o3u.wat index b67fd27e..60d0483b 100644 --- a/benchmarks/pldi2026/btree/3o3u.wat +++ b/benchmarks/pldi2026/btree/3o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o1u.wat b/benchmarks/pldi2026/btree/4o1u.wat index c74466b5..6dfc71a3 100644 --- a/benchmarks/pldi2026/btree/4o1u.wat +++ b/benchmarks/pldi2026/btree/4o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o2u.wat b/benchmarks/pldi2026/btree/4o2u.wat index 0c096699..4beac7a4 100644 --- a/benchmarks/pldi2026/btree/4o2u.wat +++ b/benchmarks/pldi2026/btree/4o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/4o3u.wat b/benchmarks/pldi2026/btree/4o3u.wat index dc2a36e6..1fac0984 100644 --- a/benchmarks/pldi2026/btree/4o3u.wat +++ b/benchmarks/pldi2026/btree/4o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o1u.wat b/benchmarks/pldi2026/btree/5o1u.wat index 0a4ff684..1ef41296 100644 --- a/benchmarks/pldi2026/btree/5o1u.wat +++ b/benchmarks/pldi2026/btree/5o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o2u.wat b/benchmarks/pldi2026/btree/5o2u.wat index 51775f0e..432244e3 100644 --- a/benchmarks/pldi2026/btree/5o2u.wat +++ b/benchmarks/pldi2026/btree/5o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/5o3u.wat b/benchmarks/pldi2026/btree/5o3u.wat index c18b66f6..05889194 100644 --- a/benchmarks/pldi2026/btree/5o3u.wat +++ b/benchmarks/pldi2026/btree/5o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o1u.wat b/benchmarks/pldi2026/btree/6o1u.wat index 1d55287b..7302e350 100644 --- a/benchmarks/pldi2026/btree/6o1u.wat +++ b/benchmarks/pldi2026/btree/6o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o2u.wat b/benchmarks/pldi2026/btree/6o2u.wat index 804c345f..8c22aa9c 100644 --- a/benchmarks/pldi2026/btree/6o2u.wat +++ b/benchmarks/pldi2026/btree/6o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/6o3u.wat b/benchmarks/pldi2026/btree/6o3u.wat index b4fc26a7..ee7d08bb 100644 --- a/benchmarks/pldi2026/btree/6o3u.wat +++ b/benchmarks/pldi2026/btree/6o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o1u.wat b/benchmarks/pldi2026/btree/7o1u.wat index e865bc50..576560fe 100644 --- a/benchmarks/pldi2026/btree/7o1u.wat +++ b/benchmarks/pldi2026/btree/7o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o2u.wat b/benchmarks/pldi2026/btree/7o2u.wat index 2169d606..d8c85450 100644 --- a/benchmarks/pldi2026/btree/7o2u.wat +++ b/benchmarks/pldi2026/btree/7o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/7o3u.wat b/benchmarks/pldi2026/btree/7o3u.wat index 16057c8c..0f7fd87a 100644 --- a/benchmarks/pldi2026/btree/7o3u.wat +++ b/benchmarks/pldi2026/btree/7o3u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/8o1u.wat b/benchmarks/pldi2026/btree/8o1u.wat index 3af9992f..9f76c0a1 100644 --- a/benchmarks/pldi2026/btree/8o1u.wat +++ b/benchmarks/pldi2026/btree/8o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/9o1u.wat b/benchmarks/pldi2026/btree/9o1u.wat index e8259458..8686ccde 100644 --- a/benchmarks/pldi2026/btree/9o1u.wat +++ b/benchmarks/pldi2026/btree/9o1u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 diff --git a/benchmarks/pldi2026/btree/9o2u.wat b/benchmarks/pldi2026/btree/9o2u.wat index ba0affca..fff6815d 100644 --- a/benchmarks/pldi2026/btree/9o2u.wat +++ b/benchmarks/pldi2026/btree/9o2u.wat @@ -7,7 +7,7 @@ (import "i32" "symbolic" (func (;0;) (type 0))) (import "i32" "sym_assume" (func (;1;) (type 1))) (import "i32" "sym_assert" (func (;2;) (type 1))) - ;; (import "sym" "get_sym_int32" (func (;3;) (type 0))) + (import "sym" "get_sym_int32" (func (;3;) (type 0))) (func (;4;) (type 0) (param i32) (result i32) i32.const 0 local.get 0 From f51290d863ab0a4f15f42f3983c5267437b1b0dd Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 22:53:56 -0400 Subject: [PATCH 68/82] a test entry that compile btree cases --- .../scala/wasm/StagedConcolicMiniWasm.scala | 35 ++++++++--- .../scala/genwasym/TestBenchmarkBtree.scala | 63 +++++++++++++++++++ 2 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 src/test/scala/genwasym/TestBenchmarkBtree.scala diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index cafddbf0..b6e830d4 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -152,6 +152,21 @@ trait StagedWasmEvaluator extends SAIOps { () } + def evalSymbolic(ty: ValueType, + rest: List[Instr], + kont: Context => Rep[Cont[Unit]], + mkont: Rep[MCont[Unit]], + trail: Trail[Unit])(implicit ctx: Context) = { + Stack.popC(ty) + val id = Stack.popS(ty) + val symVal = id.makeSymbolic(ty) + val num = SymEnv.read(symVal.s) + Stack.pushC(StagedConcreteNum(ty, num)) + Stack.pushS(symVal) + val newCtx = ctx.pop()._2.push(ty) + eval(rest, kont, mkont, trail)(newCtx) + } + def eval(insts: List[Instr], kont: Context => Rep[Cont[Unit]], mkont: Rep[MCont[Unit]], @@ -174,15 +189,7 @@ trait StagedWasmEvaluator extends SAIOps { Stack.pushS(toStagedSymbolicNum(num)) val newCtx = ctx.push(num.tipe(module)) eval(rest, kont, mkont, trail)(newCtx) - case Symbolic(ty) => - Stack.popC(ty) - val id = Stack.popS(ty) - val symVal = id.makeSymbolic(ty) - val num = SymEnv.read(symVal.s) - Stack.pushC(StagedConcreteNum(ty, num)) - Stack.pushS(symVal) - val newCtx = ctx.pop()._2.push(ty) - eval(rest, kont, mkont, trail)(newCtx) + case Symbolic(ty) => evalSymbolic(ty, rest, kont, mkont, trail)(ctx) case LocalGet(i) => Stack.pushC(Frames.getC(i)) Stack.pushS(Frames.getS(i)) @@ -530,7 +537,15 @@ trait StagedWasmEvaluator extends SAIOps { val s = Stack.popS(ty) runtimeAssert(v.toInt != 0) eval(rest, kont, mkont, trail)(newCtx) - case Import(_, _, _) => throw new Exception(s"Unknown import at $funcIndex") + case Import("i32", "symbolic", _) => + evalSymbolic(NumType(I32Type), rest, kont, mkont, trail)(ctx) + case Import("i32", "sym_assume", _) => + // TODO: implement sym_assume + eval(rest, kont, mkont, trail)(ctx.pop()._2) + case Import("i32", "sym_assert", _) => + // TODO: implement sym_assert + eval(rest, kont, mkont, trail)(ctx.pop()._2) + case Import(m, f, _) => throw new Exception(s"Unknown import $m.$f at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") } } diff --git a/src/test/scala/genwasym/TestBenchmarkBtree.scala b/src/test/scala/genwasym/TestBenchmarkBtree.scala new file mode 100644 index 00000000..edec4975 --- /dev/null +++ b/src/test/scala/genwasym/TestBenchmarkBtree.scala @@ -0,0 +1,63 @@ +package gensym.wasm + +import org.scalatest.FunSuite + +import lms.core.stub.Adapter + +import gensym.wasm.miniwasm.{ModuleInstance} +import gensym.wasm.parser._ +import gensym.wasm.stagedconcolicminiwasm._ + +// This 'test file' is not intended to test functionality, but to generate compiled code for btree benchmarks +class TestBenchmarkBtree extends FunSuite { + def compileToCpp(filename: String, + main: Option[String] = None) = { + import sys.process._ + + println(s"Compiling $filename to C++") + val moduleInst = ModuleInstance(Parser.parseFile(filename)) + val cppFile = s"$filename.cpp" + val generated = WasmToCppCompiler.compile(moduleInst, main, false) + + val code = generated.source + val writer = new java.io.PrintWriter(new java.io.File(cppFile)) + try { + writer.write(code) + } finally { + writer.close() + } + } + + def compileDirToCpp(dir: String, + main: Option[String] = None) = { + import java.io.File + val d = new File(dir) + d.listFiles().filter(_.getName.endsWith(".wat")).foreach { file => + compileToCpp(file.getAbsolutePath, main) + } + } + + // only test concrete execution and its result + def testFileConcreteCpp(filename: String, main: Option[String] = None, expect: Option[List[Float]] = None) = { + val moduleInst = ModuleInstance(Parser.parseFile(filename)) + val cppFile = s"$filename.cpp" + val exe = s"$cppFile.exe" + WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, "NO_INFO", "RUN_ONCE", "USE_IMM") + + import sys.process._ + val result = s"./$exe".!! + println(result) + + expect.map(vs => { + val stackValues = result + .split("Stack contents: \n")(1) + .split("\n") + .map(_.toFloat) + .toList + assert(vs == stackValues) + }) + } + + test("compile-btree-benchmarks") { compileDirToCpp("./benchmarks/pldi2026/btree/", Some("main")) } + +} From 832af8b5219144777f2fef0ba632ecf226e699d7 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Tue, 28 Oct 2025 23:08:27 -0400 Subject: [PATCH 69/82] a compile script in python --- benchmarks/pldi2026/btree/compile.py | 74 ++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 benchmarks/pldi2026/btree/compile.py diff --git a/benchmarks/pldi2026/btree/compile.py b/benchmarks/pldi2026/btree/compile.py new file mode 100644 index 00000000..af98295d --- /dev/null +++ b/benchmarks/pldi2026/btree/compile.py @@ -0,0 +1,74 @@ +import sys +import subprocess +from pathlib import Path + +#!/usr/bin/env python3 + +# Compile all .cpp files in this script's directory into executables with the same stem. +# Usage: python compile.py [extra g++ flags...] + +HERE = Path(__file__).resolve().parent +CPP_FILES = sorted(HERE.glob("*.cpp")) + +if not CPP_FILES: + print(f"No .cpp files found in {HERE}") + sys.exit(0) + +DEFAULT_FLAGS = [ + "-std=c++17", + "-g", + "-O0", + "-Wall", + "-Wextra", + "-DUSE_IMM", + "-I/home/zdh/WorkSpace/GenSym/headers", + "-lz3", + "-DENABLE_PROFILE_TIME", + "-DNO_REUSE", +] +EXTRA_FLAGS = sys.argv[1:] +FLAGS = DEFAULT_FLAGS + EXTRA_FLAGS + + +def compile_all(cpp_files=None, flags=None): + if cpp_files is None: + cpp_files = CPP_FILES + if flags is None: + flags = FLAGS + + compiled_total = 0 + compiled_success = 0 + compiled_failed = 0 + + for cpp in cpp_files: + out = cpp.with_suffix(".exe") # foo.cpp -> ./foo + cmd = ["g++", str(cpp), "-o", str(out)] + flags + print("Compiling:", cpp.name) + try: + proc = subprocess.run(cmd, capture_output=True, text=True) + except FileNotFoundError: + print("Error: g++ not found. Install a C++ compiler.") + sys.exit(1) + + compiled_total += 1 + if proc.returncode == 0: + compiled_success += 1 + print(" -> OK:", out.name) + else: + compiled_failed += 1 + print(" -> FAILED:", cpp.name) + if proc.stdout: + print(proc.stdout.strip()) + if proc.stderr: + print(proc.stderr.strip()) + + print() + print("Overall summary:") + print(f" Files compiled: {compiled_total}") + print(f" Succeeded: {compiled_success}") + print(f" Failed: {compiled_failed}") + return compiled_total, compiled_success, compiled_failed + + +if __name__ == "__main__": + compile_all() From 94fe90109801d96a4cbd9121c20460c0ab23df2b Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 29 Oct 2025 21:49:31 -0400 Subject: [PATCH 70/82] avoid some usage of fun --- headers/wasm/controls.hpp | 50 ++++++++++++++++++- .../scala/wasm/StagedConcolicMiniWasm.scala | 38 +++++++++----- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/headers/wasm/controls.hpp b/headers/wasm/controls.hpp index 97ba0130..ae099782 100644 --- a/headers/wasm/controls.hpp +++ b/headers/wasm/controls.hpp @@ -4,10 +4,58 @@ #include +#include +#include #include -using MCont_t = std::function; +class MContRepr; +struct MCont_t { + std::shared_ptr ptr; + MCont_t() : ptr(nullptr) {} + MCont_t(const MCont_t &p) : ptr(p.ptr) {} + MCont_t(std::shared_ptr p) : ptr(p) {} + MCont_t(std::function haltK) + : ptr(std::make_shared(haltK)) {} + bool is_null() const { return ptr == nullptr; } + + std::monostate enter(); +}; using Cont_t = std::function; +class MContRepr { +public: + MContRepr(Cont_t cont, MCont_t mcont) : cont(cont), mcont(mcont) {} + + MContRepr(std::function haltK) + : cont([=](MCont_t) { + // std::cout << "Halting the program..." << std::endl; + + return haltK(std::monostate{}); + }), + mcont() {} + + MContRepr() : cont(nullptr), mcont() {} + + std::monostate enter() { + // std::cout << "Entering MCont\n"; + // std::cout << "Cont cont: " << (cont ? "valid" : "null") << "\n"; + // std::cout << "MCont mcont: " << (mcont ? "valid" : "null") << "\n"; + if (mcont.is_null()) { + return cont(std::make_shared( + MContRepr())); // when mcont is null, we pass a dummy MContRepr + } + return cont(mcont); + } + +private: + Cont_t cont; + MCont_t mcont; +}; + +inline MCont_t prependCont(Cont_t k, MCont_t mcont) { + return std::make_shared(k, mcont); +} + +inline std::monostate MCont_t::enter() { return ptr->enter(); } struct Control { Cont_t cont; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index b6e830d4..ec91e94f 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -119,15 +119,13 @@ trait StagedWasmEvaluator extends SAIOps { } } - type MCont[A] = Unit => A + class MCont[A] type Cont[A] = (MCont[A]) => A type Trail[A] = List[Context => Rep[Cont[A]]] // a cache storing the compiled code for each function, to reduce re-compilation val compileCache = new HashMap[Int, Rep[(MCont[Unit]) => Unit]] - def makeDummy: Rep[Unit] = "dummy".reflectCtrlWith[Unit]() - def funHere[A:Manifest,B:Manifest](f: Rep[A] => Rep[B], dummy: Rep[Unit]): Rep[A => B] = { // to avoid LMS lifting a function, we create a dummy node and read it inside function fun((x: Rep[A]) => { @@ -136,6 +134,20 @@ trait StagedWasmEvaluator extends SAIOps { }) } + def makeInitMCont[A:Manifest](f: Rep[Unit => A]): Rep[MCont[A]] = { + "make-init-mcont".reflectCtrlWith[MCont[A]](f) + } + + implicit class MContOps[A:Manifest](mk: Rep[MCont[A]]) { + def prependCont(k: Rep[Cont[A]]): Rep[MCont[A]] = { + "mcont-prepend".reflectCtrlWith[MCont[A]](mk, k) + } + + def enter(): Rep[A] = { + "mcont-enter".reflectCtrlWith[A](mk) + } + } + trait Control // Save the current control information into a structure Control @@ -308,7 +320,6 @@ trait StagedWasmEvaluator extends SAIOps { // the type system guarantees that we will never take more than the input size from the stack val funcTy = ty.funcType val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size - val dummy = makeDummy def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the block, stackSize =", Stack.size) val offset = restCtx.stackTypes.size - exitSize @@ -321,7 +332,6 @@ trait StagedWasmEvaluator extends SAIOps { case Loop(ty, inner) => val funcTy = ty.funcType val exitSize = ctx.stackTypes.size - funcTy.inps.size + funcTy.out.size - val dummy = makeDummy def restK(restCtx: Context): Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { info(s"Exiting the loop, stackSize =", Stack.size) val offset = restCtx.stackTypes.size - exitSize @@ -454,7 +464,7 @@ trait StagedWasmEvaluator extends SAIOps { } } - def forwardKont: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => mk(())) + def forwardKont: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => mk.enter()) def evalCall(rest: List[Instr], @@ -481,7 +491,7 @@ trait StagedWasmEvaluator extends SAIOps { val offset = ctx.stackTypes.size - ty.out.size Stack.shiftC(offset, ty.out.size) Stack.shiftS(offset, ty.out.size) - mk(()) + mk.enter() }) eval(body, retK _, mk, retK _::Nil)(Context(Nil, locals)) }) @@ -510,10 +520,7 @@ trait StagedWasmEvaluator extends SAIOps { Frames.popFrameS(locals.size) eval(rest, kont, mk, trail)(newCtx.copy(stackTypes = ty.out.reverse ++ ctx.stackTypes.drop(ty.inps.size))) }) - val dummy = makeDummy - val newMKont: Rep[MCont[Unit]] = funHere((_u: Rep[Unit]) => { - restK(mkont) - }, dummy) + val newMKont: Rep[MCont[Unit]] = mkont.prependCont(restK) Frames.pushFrameC(locals) Frames.pushFrameS(locals) Frames.putAllC(argsC) @@ -672,7 +679,7 @@ trait StagedWasmEvaluator extends SAIOps { ExploreTree.fillWithFinished() "no-op".reflectCtrlWith[Unit]() } - val temp: Rep[MCont[Unit]] = topFun(haltK) + val temp: Rep[MCont[Unit]] = makeInitMCont(topFun(haltK)) evalTop(temp, main) } @@ -1356,6 +1363,7 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { else if (m.toString.endsWith("I64V")) "I64V" else if (m.toString.endsWith("SymVal")) "SymVal" else if (m.toString.endsWith("Snapshot")) "Snapshot_t" + else if (m.toString.endsWith("MCont[Unit]")) "MCont_t" else super.remap(m) } @@ -1547,6 +1555,12 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("ExploreTree.dump_graphviz("); shallow(f); emit(")") case Node(_, "sym-not", List(s), _) => shallow(s); emit(".negate()") + case Node(_, "make-init-mcont", List(haltK), _) => + emit("MCont_t("); shallow(haltK); emit(")") + case Node(_, "mcont-prepend", List(mkont, kont), _) => + emit("prependCont("); shallow(kont); emit(", "); shallow(mkont); emit(")") + case Node(_, "mcont-enter", List(mkont), _) => + shallow(mkont); emit(".enter()") case Node(_, "dummy", _, _) => emit("std::monostate()") case Node(_, "dummy-op", _, _) => emit("std::monostate()") case Node(_, "no-op", _, _) => From ae49b39807f3366798fcd6e15966050753c18502 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 29 Oct 2025 21:57:30 -0400 Subject: [PATCH 71/82] remove an unused function --- .../scala/genwasym/TestBenchmarkBtree.scala | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/test/scala/genwasym/TestBenchmarkBtree.scala b/src/test/scala/genwasym/TestBenchmarkBtree.scala index edec4975..8e9bc0c2 100644 --- a/src/test/scala/genwasym/TestBenchmarkBtree.scala +++ b/src/test/scala/genwasym/TestBenchmarkBtree.scala @@ -37,27 +37,6 @@ class TestBenchmarkBtree extends FunSuite { } } - // only test concrete execution and its result - def testFileConcreteCpp(filename: String, main: Option[String] = None, expect: Option[List[Float]] = None) = { - val moduleInst = ModuleInstance(Parser.parseFile(filename)) - val cppFile = s"$filename.cpp" - val exe = s"$cppFile.exe" - WasmToCppCompiler.compileToExe(moduleInst, main, cppFile, exe, true, optimizeLevel=0, "NO_INFO", "RUN_ONCE", "USE_IMM") - - import sys.process._ - val result = s"./$exe".!! - println(result) - - expect.map(vs => { - val stackValues = result - .split("Stack contents: \n")(1) - .split("\n") - .map(_.toFloat) - .toList - assert(vs == stackValues) - }) - } - test("compile-btree-benchmarks") { compileDirToCpp("./benchmarks/pldi2026/btree/", Some("main")) } } From 2e568515d4a9e63defa9c045c2117bb3e1f1cb3a Mon Sep 17 00:00:00 2001 From: ahuoguo Date: Fri, 31 Oct 2025 11:33:42 -0400 Subject: [PATCH 72/82] nontermination (if loop termination depends on symbolic value, it will explode the user's stack instead, now it gets out of bounds for the concrete stack in c++) --- benchmarks/wasm/diverge.wat | 33 +++++++++++++++++++ .../genwasym/TestStagedConcolicEval.scala | 5 +++ 2 files changed, 38 insertions(+) create mode 100644 benchmarks/wasm/diverge.wat diff --git a/benchmarks/wasm/diverge.wat b/benchmarks/wasm/diverge.wat new file mode 100644 index 00000000..8de7dcc1 --- /dev/null +++ b/benchmarks/wasm/diverge.wat @@ -0,0 +1,33 @@ +(module $diverge + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func)) + (type (;2;) (func (param i32))) + (import "console" "assert" (func (;0;) (type 2))) + (import "console" "log" (func (;1;) (type 2))) + ;; f x = if x == 0 then 42 else f x + (func (;2;) (type 0) (param i32) (result i32) + local.get 0 + i32.const 0 + i32.eq + if (result i32) + i32.const 42 + else + local.get 0 + call 1 + local.get 0 + call 2 + i32.const 0 + call 0 + unreachable + end + ) + (func $real_main (;2;) (type 1) + i32.const 0 + i32.symbolic + call 2 + drop + ) + (start 3) + (export "main" (func 3)) + +) \ No newline at end of file diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index 86f55daa..d1590f6a 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -178,4 +178,9 @@ class TestStagedConcolicEval extends FunSuite { test("small-snapshot-concrete") { testFileConcreteCpp("./benchmarks/wasm/compare_wasp/small-snapshot.wat", Some("main")) } + + // test("diverge") { + // testFileConcolicCpp("./benchmarks/wasm/diverge.wat", Some("main")) + // } + } From c8e629f54c0f1bb20866ad3ea09e4d2f8daf3ca6 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 3 Nov 2025 14:19:22 -0500 Subject: [PATCH 73/82] support sym_assume to prune subtrees --- headers/wasm/concolic_driver.hpp | 3 +- headers/wasm/symbolic_rt.hpp | 94 ++++++++++++++++++- .../scala/wasm/StagedConcolicMiniWasm.scala | 45 ++++++++- 3 files changed, 137 insertions(+), 5 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 80ff38d5..2a9a994d 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -48,7 +48,7 @@ class ManagedConcolicCleanup { if (driver.tree_file.has_value()) ExploreTree.dump_graphviz(driver.tree_file.value()); - // Clear the symbol bookkeeper + // Clear the symbol bookkeeper SymBookKeeper.clear(); } }; @@ -134,6 +134,7 @@ inline void ConcolicDriver::main_exploration_loop() { inline void ConcolicDriver::run() { main_exploration_loop(); + ExploreTree.print_overall_result(); Profile.print_summary(); } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 6edef6ee..2bcfe7ac 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -543,6 +543,7 @@ struct NodeBox { std::monostate fillFailedNode(); std::monostate fillUnreachableNode(); std::monostate fillSnapshotNode(Snapshot_t snapshot); + std::monostate fillNotToExploreNode(); bool isUnexplored() const; std::vector collect_path_conds(); int min_cost_of_reaching_here(); @@ -664,6 +665,22 @@ struct UnExploredNode : Node { } }; +struct NotToExploreNode : Node { + NotToExploreNode() {} + std::string to_string() override { return "NotToExploreNode"; } + +protected: + void generate_dot(std::ostream &os, int parent_dot_id, + const std::string &edge_label) override { + int current_node_dot_id = current_id++; + graphviz_node(os, current_node_dot_id, "NotToExplore", "box", "grey"); + + if (parent_dot_id != -1) { + graphviz_edge(os, parent_dot_id, current_node_dot_id, edge_label); + } + } +}; + struct SnapshotNode : Node { SnapshotNode(Snapshot_t snapshot) : snapshot(snapshot) {} std::string to_string() override { return "SnapshotNode"; } @@ -761,6 +778,15 @@ inline std::monostate NodeBox::fillSnapshotNode(Snapshot_t snapshot) { return std::monostate(); } +inline std::monostate NodeBox::fillNotToExploreNode() { + if (this->isUnexplored()) { + node = std::make_unique(); + } else { + assert(dynamic_cast(node.get()) != nullptr); + } + return std::monostate(); +} + inline std::monostate NodeBox::fillFinishedNode() { if (this->isUnexplored()) { node = std::make_unique(); @@ -896,6 +922,10 @@ class ExploreTree_t { return std::monostate(); } + std::monostate fillNotToExploredNode() { + return cursor->fillNotToExploreNode(); + } + bool worth_to_create_snapshot() { if (!ENABLE_COST_MODEL) { return REUSE_SNAPSHOT; @@ -911,8 +941,8 @@ class ExploreTree_t { auto parent_cost = cursor->parent ? cursor->parent->min_cost_of_reaching_here() : 0; auto exec_from_parent_cost = reach_parent_cost + cursor->instr_cost; - GENSYM_INFO("The score of snapshot tendency: " + std::to_string(exec_from_parent_cost - - snapshot_cost)); + GENSYM_INFO("The score of snapshot tendency: " + + std::to_string(exec_from_parent_cost - snapshot_cost)); return snapshot_cost <= exec_from_parent_cost; } @@ -924,6 +954,7 @@ class ExploreTree_t { if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); int cost_from_parent = CostManager.dump_instr_cost(); + cursor->instr_cost = cost_from_parent; if (branch) { true_branch_cov_map[if_else_node->id] = true; if (worth_to_create_snapshot()) { @@ -947,6 +978,26 @@ class ExploreTree_t { return std::monostate(); } + std::monostate moveCursorNoControl(bool branch) { + Profile.step(StepProfileKind::CURSOR_MOVE); + assert(cursor != nullptr); + auto if_else_node = dynamic_cast(cursor->node.get()); + assert( + if_else_node != nullptr && + "Can't move cursor when the branch node is not initialized correctly!"); + int cost_from_parent = CostManager.dump_instr_cost(); + cursor->instr_cost = cost_from_parent; + if (branch) { + true_branch_cov_map[if_else_node->id] = true; + if_else_node->false_branch->fillNotToExploreNode(); + cursor = if_else_node->true_branch.get(); + } else { + assert(false && + "moveCursorNoControl should not be used for false branch"); + } + return std::monostate(); + } + std::monostate print() { std::cout << root->node->to_string() << std::endl; return std::monostate(); @@ -966,6 +1017,45 @@ class ExploreTree_t { return std::monostate(); } + std::monostate print_overall_result() { + // Print how many paths have been explored, how many paths are unreachable, + // how many paths are failed, how many paths are finished successfully + int unexplored_count = 0; + int finished_count = 0; + int failed_count = 0; + int not_to_explore_count = 0; + int unreachable_count = 0; + std::function dfs = [&](NodeBox *node) { + if (auto if_else_node = dynamic_cast(node->node.get())) { + dfs(if_else_node->true_branch.get()); + dfs(if_else_node->false_branch.get()); + } else if (dynamic_cast(node->node.get())) { + unexplored_count += 1; + } else if (dynamic_cast(node->node.get())) { + finished_count += 1; + } else if (dynamic_cast(node->node.get())) { + failed_count += 1; + } else if (dynamic_cast(node->node.get())) { + unreachable_count += 1; + } else if (dynamic_cast(node->node.get())) { + // Snapshot node is considered unexplored + unexplored_count += 1; + } else if (dynamic_cast(node->node.get())) { + not_to_explore_count += 1; + } else { + throw std::runtime_error("Unknown node type in explore tree"); + } + }; + dfs(root.get()); + std::cout << "Explore Tree Overall Result:" << std::endl; + std::cout << " Unexplored paths: " << unexplored_count << std::endl; + std::cout << " Finished paths: " << finished_count << std::endl; + std::cout << " Failed paths: " << failed_count << std::endl; + std::cout << " Unreachable paths: " << unreachable_count << std::endl; + std::cout << " NotToExplore paths: " << not_to_explore_count << std::endl; + return std::monostate(); + } + NodeBox *pick_unexplored() { // Pick an unexplored node from the tree // For now, we just iterate through the tree and return the first unexplored diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index ec91e94f..308ce55a 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -31,6 +31,12 @@ object Counter { dict.clear() } + def getId(): Int = { + val id = currentId + currentId += 1 + id + } + def getId(wir: WIR, nth: Int = 0): Int = { if (dict.contains((wir, nth))) { dict((wir, nth)) @@ -547,8 +553,28 @@ trait StagedWasmEvaluator extends SAIOps { case Import("i32", "symbolic", _) => evalSymbolic(NumType(I32Type), rest, kont, mkont, trail)(ctx) case Import("i32", "sym_assume", _) => - // TODO: implement sym_assume - eval(rest, kont, mkont, trail)(ctx.pop()._2) + // symbolic assume is just like an if else that only has one branch, while another + // is marked as not-to-explore + val (condTy, newCtx) = ctx.pop() + Predef.assert(condTy == NumType(I32Type), s"sym_assume only supports i32 condition, get $condTy") + val cond = Stack.popC(condTy) + val symCond = Stack.popS(condTy) + val id = Counter.getId() + ExploreTree.fillWithIfElse(symCond.s, id) + def thnK: Rep[Cont[Unit]] = topFun((mk: Rep[MCont[Unit]]) => { + info(s"Successfully assumed condition at $id") + eval(rest, kont, mk, trail)(newCtx) + }) + if (cond.toInt != 0) { + ExploreTree.moveCursor(true) + eval(rest, kont, mkont, trail)(newCtx) + } else { + val control = makeControl(thnK, mkont) + ExploreTree.moveCursor(false, control) + // just stop the execution at here + ExploreTree.fillWithNotToExplore() + } + () case Import("i32", "sym_assert", _) => // TODO: implement sym_assert eval(rest, kont, mkont, trail)(ctx.pop()._2) @@ -637,6 +663,8 @@ trait StagedWasmEvaluator extends SAIOps { def evalTop(mkont: Rep[MCont[Unit]], main: Option[String]): Rep[Unit] = { Counter.reset() + Predef.println("[DEBUG]" + module) + Predef.println("[DEBUG] module.defs: " + module.defs) val funBody: FuncBodyDef = main match { case Some(func_name) => module.defs.flatMap({ @@ -889,6 +917,10 @@ trait StagedWasmEvaluator extends SAIOps { "tree-fill-if-else".reflectCtrlWith[Unit](s, id) } + def fillWithNotToExplore(): Rep[Unit] = { + "tree-fill-not-to-explore".reflectCtrlWith[Unit]() + } + def fillWithFinished(): Rep[Unit] = { "tree-fill-finished".reflectCtrlWith[Unit]() } @@ -898,6 +930,11 @@ trait StagedWasmEvaluator extends SAIOps { "tree-move-cursor".reflectCtrlWith[Unit](branch, control) } + def moveCursor(branch: Boolean): Rep[Unit] = { + // when moving cursor from to an unexplored node, we need to change the reuse state + "tree-move-cursor-no-control".reflectCtrlWith[Unit](branch) + } + def print(): Rep[Unit] = { "tree-print".reflectCtrlWith[Unit]() } @@ -1543,10 +1580,14 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("GENSYM_ASSERT("); shallow(cond); emit(")") case Node(_, "tree-fill-if-else", List(sym, id), _) => emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(", "); emit(id.toString); emit(")") + case Node(_, "tree-fill-not-to-explore", List(), _) => + emit("ExploreTree.fillNotToExploredNode()") case Node(_, "tree-fill-finished", List(), _) => emit("ExploreTree.fillFinishedNode()") case Node(_, "tree-move-cursor", List(b, snapshot), _) => emit("ExploreTree.moveCursor("); shallow(b); emit(", "); shallow(snapshot); emit(")") + case Node(_, "tree-move-cursor-no-control", List(b), _) => + emit("ExploreTree.moveCursorNoControl("); shallow(b); emit(")") case Node(_, "add-instr-cost", List(n), _) => emit("CostManager.add_instr_cost("); shallow(n); emit(")") case Node(_, "tree-print", List(), _) => From 2ced35434d68be1cc139ab6f315ab367d861787a Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 3 Nov 2025 15:20:00 -0500 Subject: [PATCH 74/82] support write profile file --- benchmarks/pldi2026/btree/compile.py | 2 + headers/wasm/concolic_driver.hpp | 7 +++- headers/wasm/output_report.hpp | 54 ++++++++++++++++++++++++ headers/wasm/profile.hpp | 60 ++++++++++++++++++++++++++- headers/wasm/symbolic_rt.hpp | 61 ++++++++++++++++++---------- 5 files changed, 160 insertions(+), 24 deletions(-) create mode 100644 headers/wasm/output_report.hpp diff --git a/benchmarks/pldi2026/btree/compile.py b/benchmarks/pldi2026/btree/compile.py index af98295d..8c0b5372 100644 --- a/benchmarks/pldi2026/btree/compile.py +++ b/benchmarks/pldi2026/btree/compile.py @@ -45,6 +45,8 @@ def compile_all(cpp_files=None, flags=None): cmd = ["g++", str(cpp), "-o", str(out)] + flags print("Compiling:", cpp.name) try: + print(" Executing command:") + print(" ", " ".join(cmd)) proc = subprocess.run(cmd, capture_output=True, text=True) except FileNotFoundError: print("Error: g++ not found. Install a C++ compiler.") diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 2a9a994d..e13e5882 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -7,6 +7,7 @@ #include "smt_solver.hpp" #include "symbolic_rt.hpp" #include "utils.hpp" +#include "output_report.hpp" #include #include #include @@ -48,7 +49,7 @@ class ManagedConcolicCleanup { if (driver.tree_file.has_value()) ExploreTree.dump_graphviz(driver.tree_file.value()); - // Clear the symbol bookkeeper + // Clear the symbol bookkeeper SymBookKeeper.clear(); } }; @@ -134,8 +135,10 @@ inline void ConcolicDriver::main_exploration_loop() { inline void ConcolicDriver::run() { main_exploration_loop(); - ExploreTree.print_overall_result(); + auto overall = ExploreTree.read_current_overall_result(); + overall.print(); Profile.print_summary(); + dump_all_summary_json(Profile, overall); } static void start_concolic_execution_with( diff --git a/headers/wasm/output_report.hpp b/headers/wasm/output_report.hpp new file mode 100644 index 00000000..a1a08f0b --- /dev/null +++ b/headers/wasm/output_report.hpp @@ -0,0 +1,54 @@ +#ifndef WASM_OUTPUT_REPORT_HPP +#define WASM_OUTPUT_REPORT_HPP + +#include "profile.hpp" +#include "symbolic_rt.hpp" +#include "config.hpp" +#include + +inline void dump_all_summary_json(const Profile_t &profile, + const OverallResult &overall) { + // use environment variable OUTPUT_DIR to config particular output directory + // use environment variable OUTPUT_DIR to config particular output directory + const char *output_dir = std::getenv("OUTPUT_DIR"); + if (output_dir == nullptr) { + return; + } + + std::filesystem::path outdir(output_dir); + + std::filesystem::path report_path = + outdir / std::filesystem::path("concolic_execution_report.json"); + + auto parent = report_path.parent_path(); + if (!parent.empty()) { + std::error_code ec; + std::filesystem::create_directories(parent, ec); + if (ec) { + throw std::runtime_error("Failed to create output directory: " + + ec.message()); + } + } + + std::ofstream ofs(report_path); + if (!ofs.is_open()) { + throw std::runtime_error("Failed to open " + report_path.string() + + " for writing"); + } + + // Simple JSON dump (pretty-printed) + ofs << "{\n"; + ofs << " \"unexplored_count\": " << overall.unexplored_count << ",\n"; + ofs << " \"finished_count\": " << overall.finished_count << ",\n"; + ofs << " \"failed_count\": " << overall.failed_count << ",\n"; + ofs << " \"not_to_explore_count\": " << overall.not_to_explore_count + << ",\n"; + ofs << " \"unreachable_count\": " << overall.unreachable_count; + if (PROFILE_STEP || PROFILE_TIME) { + ofs << ",\n"; + profile.write_as_json(ofs); + } + ofs << "}\n"; + ofs.close(); +} +#endif // WASM_OUTPUT_REPORT_HPP \ No newline at end of file diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index 9814b5eb..ba8194c7 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -116,12 +116,70 @@ class Profile_t { } } + void write_as_json(std::ostream &os) const { + os << " \"profile_summary\": {\n"; + if (PROFILE_STEP) { + os << " \"total_push_operations\": " + << op_count[static_cast(StepProfileKind::PUSH)] << ",\n"; + os << " \"total_pop_operations\": " + << op_count[static_cast(StepProfileKind::POP)] << ",\n"; + os << " \"total_peek_operations\": " + << op_count[static_cast(StepProfileKind::PEEK)] << ",\n"; + os << " \"total_shift_operations\": " + << op_count[static_cast(StepProfileKind::SHIFT)] << ",\n"; + os << " \"total_set_operations\": " + << op_count[static_cast(StepProfileKind::SET)] << ",\n"; + os << " \"total_get_operations\": " + << op_count[static_cast(StepProfileKind::GET)] << ",\n"; + os << " \"total_binary_operations\": " + << op_count[static_cast(StepProfileKind::BINARY)] + << ",\n"; + os << " \"total_tree_fill_operations\": " + << op_count[static_cast(StepProfileKind::TREE_FILL)] + << ",\n"; + os << " \"total_cursor_move_operations\": " + << op_count[static_cast(StepProfileKind::CURSOR_MOVE)] + << ",\n"; + os << " \"total_other_instructions_executed\": " << step_count + << ",\n"; + os << " \"total_mem_grow_operations\": " + << op_count[static_cast(StepProfileKind::MEM_GROW)] + << ",\n"; + os << " \"total_snapshot_create_operations\": " + << op_count[static_cast(StepProfileKind::SNAPSHOT_CREATE)] + << ",\n"; + os << " \"total_sym_eval_operations\": " + << op_count[static_cast(StepProfileKind::SYM_EVAL)] + << "\n"; + } + if (PROFILE_TIME) { + os << " \"total_time_instruction_execution_s\": " + << std::setprecision(15) + << time_count[static_cast(TimeProfileKind::INSTR)] + << ",\n"; + os << " \"total_time_solver_s\": " + << std::setprecision(15) + << time_count[static_cast(TimeProfileKind::SOLVER)] + << ",\n"; + os << " \"total_time_resuming_from_snapshot_s\": " + << std::setprecision(15) + << time_count[static_cast( + TimeProfileKind::RESUME_SNAPSHOT)] + << ",\n"; + os << " \"total_time_counting_symbolic_size_s\": " + << std::setprecision(15) + << time_count[static_cast( + TimeProfileKind::COUNT_SYM_SIZE)] + << "\n"; + } + os << " }\n"; + } + // record the time spent in main instruction execution, in seconds void add_instruction_time(TimeProfileKind kind, double time) { time_count[static_cast(kind)] += time; } -private: int step_count; std::array(StepProfileKind::OperationCount)> op_count; diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 2bcfe7ac..cc1e8652 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -884,6 +885,24 @@ inline int Snapshot_t::cost_of_snapshot() { return 5.336 * (cost_of_stack_copy + cost_of_frame_copy + cost_of_memory_copy); } + +struct OverallResult { + int unexplored_count = 0; + int finished_count = 0; + int failed_count = 0; + int not_to_explore_count = 0; + int unreachable_count = 0; + + void print() { + std::cout << "Explore Tree Overall Result:" << std::endl; + std::cout << " Unexplored paths: " << unexplored_count << std::endl; + std::cout << " Finished paths: " << finished_count << std::endl; + std::cout << " Failed paths: " << failed_count << std::endl; + std::cout << " Unreachable paths: " << unreachable_count << std::endl; + std::cout << " NotToExplore paths: " << not_to_explore_count << std::endl; + } +}; + class ExploreTree_t { public: explicit ExploreTree_t() @@ -1009,6 +1028,16 @@ class ExploreTree_t { } std::monostate dump_graphviz(std::string filepath) { + std::filesystem::path out_path(filepath); + auto parent = out_path.parent_path(); + if (!parent.empty()) { + std::error_code ec; + std::filesystem::create_directories(parent, ec); + if (ec) { + throw std::runtime_error("Failed to create output directory: " + + ec.message()); + } + } std::ofstream ofs(filepath); if (!ofs.is_open()) { throw std::runtime_error("Failed to open " + filepath + " for writing"); @@ -1017,45 +1046,35 @@ class ExploreTree_t { return std::monostate(); } - std::monostate print_overall_result() { - // Print how many paths have been explored, how many paths are unreachable, - // how many paths are failed, how many paths are finished successfully - int unexplored_count = 0; - int finished_count = 0; - int failed_count = 0; - int not_to_explore_count = 0; - int unreachable_count = 0; + OverallResult read_current_overall_result() { + OverallResult result; std::function dfs = [&](NodeBox *node) { if (auto if_else_node = dynamic_cast(node->node.get())) { dfs(if_else_node->true_branch.get()); dfs(if_else_node->false_branch.get()); } else if (dynamic_cast(node->node.get())) { - unexplored_count += 1; + result.unexplored_count += 1; } else if (dynamic_cast(node->node.get())) { - finished_count += 1; + result.finished_count += 1; } else if (dynamic_cast(node->node.get())) { - failed_count += 1; + result.failed_count += 1; } else if (dynamic_cast(node->node.get())) { - unreachable_count += 1; + result.unreachable_count += 1; } else if (dynamic_cast(node->node.get())) { // Snapshot node is considered unexplored - unexplored_count += 1; + result.unexplored_count += 1; } else if (dynamic_cast(node->node.get())) { - not_to_explore_count += 1; + result.not_to_explore_count += 1; } else { throw std::runtime_error("Unknown node type in explore tree"); } }; dfs(root.get()); - std::cout << "Explore Tree Overall Result:" << std::endl; - std::cout << " Unexplored paths: " << unexplored_count << std::endl; - std::cout << " Finished paths: " << finished_count << std::endl; - std::cout << " Failed paths: " << failed_count << std::endl; - std::cout << " Unreachable paths: " << unreachable_count << std::endl; - std::cout << " NotToExplore paths: " << not_to_explore_count << std::endl; - return std::monostate(); + return result; } + std::monostate print_overall_result() {} + NodeBox *pick_unexplored() { // Pick an unexplored node from the tree // For now, we just iterate through the tree and return the first unexplored From 1818f538d45c0f2ff4f5158514ecabc61d0a83e1 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 3 Nov 2025 16:05:28 -0500 Subject: [PATCH 75/82] a script for running and cleaning up benchmark executables. --- benchmarks/pldi2026/btree/run.py | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 benchmarks/pldi2026/btree/run.py diff --git a/benchmarks/pldi2026/btree/run.py b/benchmarks/pldi2026/btree/run.py new file mode 100644 index 00000000..4cb40e1e --- /dev/null +++ b/benchmarks/pldi2026/btree/run.py @@ -0,0 +1,74 @@ +import os +import shutil +import sys +import subprocess +from pathlib import Path +import argparse + + +HERE = Path(__file__).resolve().parent +ME = Path(__file__).name + + +def is_executable(path: Path) -> bool: + if not path.is_file(): + return False + # executable bit or .exe suffix + return os.access(str(path), os.X_OK) or path.suffix.lower() == ".exe" + + +def run_all(targets: list[Path], action): + for file_path in targets: + if not is_executable(file_path): + continue + file_name = file_path.name.removesuffix(".exe") + output_path = f"{file_name}.output" + if action == "run": + env = os.environ.copy() + env.update({"OUTPUT_DIR": output_path}) + + print("Now executing: " + str(file_path)) + proc = subprocess.Popen( + [str(file_path.resolve())], stderr=subprocess.STDOUT, env=env + ) + rc = proc.wait() + + if rc != 0: + print(f"{file_name} exited with return code {rc}", file=sys.stderr) + elif action == "clean": + p = Path(output_path) + if p.exists(): + try: + if p.is_dir(): + shutil.rmtree(p) + except Exception as e: + print(f"Failed to remove {output_path}: {e}", file=sys.stderr) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "-r", + "--run-all", + action="store_true", + help="Run all compiled executables in the current directory", + ) + parser.add_argument( + "--clean", + action="store_true" + ) + args = parser.parse_args() + + if not args.run_all and not args.clean: + parser.print_help() + return 0 + + targets = list(sorted(list(Path(".").iterdir()))) + if args.run_all: + run_all(targets, action="run") + elif args.clean: + run_all(targets, action="clean") + + + +if __name__ == "__main__": + sys.exit(main()) From 6dd52b2a553306ea2ede2a8e14d1469fd465f3a2 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Mon, 3 Nov 2025 20:05:32 -0500 Subject: [PATCH 76/82] never build an expression twice --- benchmarks/pldi2026/btree/compile.py | 2 +- benchmarks/pldi2026/btree/run.py | 2 ++ headers/wasm/smt_solver.hpp | 28 +++++++++++++++++++++------- headers/wasm/symbolic_rt.hpp | 14 +++++++++++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/benchmarks/pldi2026/btree/compile.py b/benchmarks/pldi2026/btree/compile.py index 8c0b5372..5e1555b3 100644 --- a/benchmarks/pldi2026/btree/compile.py +++ b/benchmarks/pldi2026/btree/compile.py @@ -17,7 +17,7 @@ DEFAULT_FLAGS = [ "-std=c++17", "-g", - "-O0", + "-O3", "-Wall", "-Wextra", "-DUSE_IMM", diff --git a/benchmarks/pldi2026/btree/run.py b/benchmarks/pldi2026/btree/run.py index 4cb40e1e..b462af29 100644 --- a/benchmarks/pldi2026/btree/run.py +++ b/benchmarks/pldi2026/btree/run.py @@ -23,6 +23,8 @@ def run_all(targets: list[Path], action): continue file_name = file_path.name.removesuffix(".exe") output_path = f"{file_name}.output" + if Path(output_path).exists(): + continue if action == "run": env = os.environ.copy() env.update({"OUTPUT_DIR": output_path}) diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 5df683f7..122f18aa 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -7,6 +7,7 @@ #include "wasm/profile.hpp" #include "z3++.h" #include +#include #include #include #include @@ -15,15 +16,16 @@ class Solver { public: Solver() {} - std::optional solve(const std::vector &conditions) { + std::optional solve(std::vector &conditions) { z3::solver z3_solver(z3_ctx); z3::check_result solver_result; { + auto timer = ManagedTimer(TimeProfileKind::SOLVER); // make an conjunction of all conditions auto conjunction = to_z3_conjunction(conditions); // call z3 to solve the condition - auto timer = ManagedTimer(TimeProfileKind::SOLVER); - z3_solver.add(conjunction); // NOTE: half of the solver time is spent in solver.add + // NOTE: half of the solver time is spent in solver.add + z3_solver.add(conjunction); solver_result = z3_solver.check(); } switch (solver_result) { @@ -56,9 +58,9 @@ class Solver { } private: - z3::expr to_z3_conjunction(const std::vector &conditions) { + z3::expr to_z3_conjunction(std::vector &conditions) { z3::expr conjunction = z3_ctx.bool_val(true); - for (const auto &cond : conditions) { + for (auto &cond : conditions) { auto z3_cond = build_z3_expr(cond); conjunction = conjunction && z3_cond != z3_ctx.bv_val(0, 32); } @@ -70,10 +72,13 @@ class Solver { } z3::context z3_ctx; - z3::expr build_z3_expr(const SymVal &sym_val); + z3::expr build_z3_expr(SymVal &sym_val); + +private: + z3::expr build_z3_expr_aux(SymVal &sym_val); }; -inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) { +inline z3::expr Solver::build_z3_expr_aux(SymVal &sym_val) { if (auto sym = std::dynamic_pointer_cast(sym_val.symptr)) { return z3_ctx.bv_const(("s_" + std::to_string(sym->get_id())).c_str(), 32); } else if (auto concrete = @@ -150,4 +155,13 @@ inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) { } throw std::runtime_error("Unsupported symbolic value type"); } + +inline z3::expr Solver::build_z3_expr(SymVal &sym_val) { + if (sym_val.z3_expr) { + return *sym_val.z3_expr; + } + auto e = build_z3_expr_aux(sym_val); + sym_val.z3_expr = std::make_shared(e); + return e; +} #endif // SMT_SOLVER_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index cc1e8652..998af1e9 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -10,6 +10,7 @@ #include "immer/vector_transient.hpp" #include "profile.hpp" #include "utils.hpp" +#include "z3++.h" #include #include #include @@ -90,6 +91,7 @@ static std::shared_ptr ZeroByte = struct SymVal { std::shared_ptr symptr; + std::shared_ptr z3_expr; SymVal() : symptr(ZERO) {} SymVal(std::shared_ptr symptr) : symptr(symptr) {} @@ -226,11 +228,21 @@ inline SymVal SymVal::make_binary(Operation op, const SymVal &lhs, assert(lhs.symptr != nullptr && rhs.symptr != nullptr); return SymVal(SymBookKeeper.allocate(op, lhs, rhs)); } +static std::unordered_map SymbolCache; + inline SymVal SymVal::makeSymbolic() const { auto concrete = dynamic_cast(symptr.get()); if (concrete) { // If the symbolic value is a concrete value, use it to create a symbol - return SymVal(SymBookKeeper.allocate(concrete->value.toInt())); + auto id = concrete->value.toInt(); + auto it = SymbolCache.find(id); + if (it != SymbolCache.end()) { + return it->second; + } + auto sym = Symbol(id); + auto ptr = SymBookKeeper.allocate(sym); + return SymVal(ptr); + } else { throw std::runtime_error( "Cannot make symbolic a non-concrete symbolic value"); From 7cdfe5393921462c697751bc17a487eae25c54eb Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Wed, 5 Nov 2025 15:57:48 -0500 Subject: [PATCH 77/82] update sym_assert and timer --- headers/wasm/concolic_driver.hpp | 1 - headers/wasm/profile.hpp | 41 +++++++++++++++---- headers/wasm/smt_solver.hpp | 17 +++++++- headers/wasm/symbolic_rt.hpp | 4 ++ .../scala/wasm/StagedConcolicMiniWasm.scala | 12 +++++- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index e13e5882..7211a5a2 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -31,7 +31,6 @@ class ConcolicDriver { private: void main_exploration_loop(); - Solver solver; std::function entrypoint; std::optional tree_file; std::vector work_list; diff --git a/headers/wasm/profile.hpp b/headers/wasm/profile.hpp index ba8194c7..c32e2b51 100644 --- a/headers/wasm/profile.hpp +++ b/headers/wasm/profile.hpp @@ -7,6 +7,7 @@ #include #include #include +#include enum class StepProfileKind { PUSH, @@ -157,8 +158,7 @@ class Profile_t { << std::setprecision(15) << time_count[static_cast(TimeProfileKind::INSTR)] << ",\n"; - os << " \"total_time_solver_s\": " - << std::setprecision(15) + os << " \"total_time_solver_s\": " << std::setprecision(15) << time_count[static_cast(TimeProfileKind::SOLVER)] << ",\n"; os << " \"total_time_resuming_from_snapshot_s\": " @@ -191,23 +191,50 @@ class Profile_t { static Profile_t Profile; -class ManagedTimer { +class Timer { public: - ManagedTimer() = delete; - ManagedTimer(TimeProfileKind kind) : kind(kind) { + Timer() = delete; + Timer(TimeProfileKind kind) : kind(kind) { + elapsed = std::chrono::duration::zero(); start = std::chrono::high_resolution_clock::now(); } - ~ManagedTimer() { + ~Timer() { auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = end - start; + elapsed += end - start; Profile.add_instruction_time(kind, elapsed.count()); } + void stop() { elapsed += std::chrono::high_resolution_clock::now() - start; } + void resume() { start = std::chrono::high_resolution_clock::now(); } private: + std::chrono::duration elapsed; TimeProfileKind kind; std::chrono::high_resolution_clock::time_point start; }; +static std::vector TimerStack = []() { + std::vector v; + v.reserve(3); // initial capacity + return v; +}(); + +class ManagedTimer { +public: + ManagedTimer() = delete; + ManagedTimer(TimeProfileKind kind) { + if (TimerStack.size() > 0) { + TimerStack.back().stop(); + } + TimerStack.emplace_back(kind); + } + ~ManagedTimer() { + TimerStack.pop_back(); + if (TimerStack.size() > 0) { + TimerStack.back().resume(); + } + } +}; + struct CostManager_t { int instr_cost; diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 122f18aa..09c91e89 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include class Solver { @@ -73,11 +74,11 @@ class Solver { z3::context z3_ctx; z3::expr build_z3_expr(SymVal &sym_val); - -private: z3::expr build_z3_expr_aux(SymVal &sym_val); }; +static Solver solver; + inline z3::expr Solver::build_z3_expr_aux(SymVal &sym_val) { if (auto sym = std::dynamic_pointer_cast(sym_val.symptr)) { return z3_ctx.bv_const(("s_" + std::to_string(sym->get_id())).c_str(), 32); @@ -164,4 +165,16 @@ inline z3::expr Solver::build_z3_expr(SymVal &sym_val) { sym_val.z3_expr = std::make_shared(e); return e; } + +inline std::monostate GENSYM_SYM_ASSERT(SymVal &sym_cond) { + std::vector conds = ExploreTree.collect_current_path_conds(); + conds.push_back(sym_cond.negate()); + auto result = solver.solve(conds); + if (result.has_value()) { + std::cout << "Symbolic assertion failed" << std::endl; + throw std::runtime_error("Symbolic assertion failed"); + } + return std::monostate{}; +} + #endif // SMT_SOLVER_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 998af1e9..fe268ed5 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -957,6 +957,10 @@ class ExploreTree_t { return cursor->fillNotToExploreNode(); } + std::vector collect_current_path_conds() { + return cursor->collect_path_conds(); + } + bool worth_to_create_snapshot() { if (!ENABLE_COST_MODEL) { return REUSE_SNAPSHOT; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index 308ce55a..aebf11ac 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -576,7 +576,11 @@ trait StagedWasmEvaluator extends SAIOps { } () case Import("i32", "sym_assert", _) => - // TODO: implement sym_assert + val (condTy, newCtx) = ctx.pop() + val v = Stack.popC(condTy) + val s = Stack.popS(condTy) + runtimeSymAssert(s) + runtimeAssert(v.toInt != 0) eval(rest, kont, mkont, trail)(ctx.pop()._2) case Import(m, f, _) => throw new Exception(s"Unknown import $m.$f at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") @@ -715,6 +719,10 @@ trait StagedWasmEvaluator extends SAIOps { "assert-true".reflectCtrlWith[Unit](b) } + def runtimeSymAssert(s: StagedSymbolicNum): Rep[Unit] = { + "sym-assert-true".reflectCtrlWith[Unit](s.s) + } + // stack operations object Stack { def shiftC(offset: Int, size: Int) = { @@ -1578,6 +1586,8 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { emit("SymEnv.read("); shallow(sym); emit(")") case Node(_, "assert-true", List(cond), _) => emit("GENSYM_ASSERT("); shallow(cond); emit(")") + case Node(_, "sym-assert-true", List(s_cond), _) => + emit("GENSYM_SYM_ASSERT("); shallow(s_cond); emit(")") case Node(_, "tree-fill-if-else", List(sym, id), _) => emit("ExploreTree.fillIfElseNode("); shallow(sym); emit(", "); emit(id.toString); emit(")") case Node(_, "tree-fill-not-to-explore", List(), _) => From efb8144ae1bc83a0f37815b1d18aebb46498e15f Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 6 Nov 2025 11:42:51 -0500 Subject: [PATCH 78/82] refactor operator to explicit methods --- headers/wasm/concrete_rt.hpp | 124 +++++++++++++++--- headers/wasm/symbolic_rt.hpp | 68 ++++++++-- .../scala/wasm/StagedConcolicMiniWasm.scala | 75 +++++------ 3 files changed, 201 insertions(+), 66 deletions(-) diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index ea321f45..a63d2d7e 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -17,30 +17,121 @@ struct Num { Num(int64_t value) : value(value) {} Num() : value(0) {} int64_t value; + int32_t toInt() const { return static_cast(value); } + uint32_t toUInt() const { return static_cast(value); } + // Helper to create a Wasm Boolean result (1 or 0 as Num) + Num WasmBool(bool condition) const { return Num(condition ? 1 : 0); } // TODO: support different bit width operations, for now we just assume all // oprands are i32 - bool operator==(const Num &other) const { return toInt() == other.toInt(); } - bool operator!=(const Num &other) const { return !(*this == other); } - Num operator+(const Num &other) const { return Num(toInt() + other.toInt()); } - Num operator-(const Num &other) const { return Num(toInt() - other.toInt()); } - Num operator*(const Num &other) const { return Num(toInt() * other.toInt()); } - Num operator/(const Num &other) const { - if (other.toInt() == 0) { - throw std::runtime_error("Division by zero"); + // i32.eq (Equals): *this == other + inline Num i32_eq(const Num &other) const { + return WasmBool(this->toUInt() == other.toUInt()); + } + + // i32.ne (Not Equals): *this != other + inline Num i32_ne(const Num &other) const { + return WasmBool(this->toUInt() != other.toUInt()); + } + + // i32.lt_s (Signed Less Than): *this < other + inline Num i32_lt_s(const Num &other) const { + return WasmBool(this->toInt() < other.toInt()); + } + + // i32.lt_u (Unsigned Less Than): *this < other (unsigned) + inline Num i32_lt_u(const Num &other) const { + return WasmBool(this->toUInt() < other.toUInt()); + } + + // i32.le_s (Signed Less Than or Equal): *this <= other + inline Num i32_le_s(const Num &other) const { + return WasmBool(this->toInt() <= other.toInt()); + } + // i32.le_u (Unsigned Less Than or Equal): *this <= other (unsigned) + inline Num i32_le_u(const Num &other) const { + return WasmBool(this->toUInt() <= other.toUInt()); + } + + // i32.gt_s (Signed Greater Than): *this > other + inline Num i32_gt_s(const Num &other) const { + return WasmBool(this->toInt() > other.toInt()); + } + + // i32.gt_u (Unsigned Greater Than): *this > other (unsigned) + inline Num i32_gt_u(const Num &other) const { + return WasmBool(this->toUInt() > other.toUInt()); + } + + // i32.ge_s (Signed Greater Than or Equal): *this >= other + inline Num i32_ge_s(const Num &other) const { + return WasmBool(this->toInt() >= other.toInt()); + } + + // i32.ge_u (Unsigned Greater Than or Equal): *this >= other (unsigned) + inline Num i32_ge_u(const Num &other) const { + return WasmBool(this->toUInt() >= other.toUInt()); + } + + // i32.add (Wrapping addition) + inline Num i32_add(const Num &other) const { + uint32_t result_u = this->toUInt() + other.toUInt(); + return Num(static_cast(result_u)); + } + + // i32.sub (Wrapping subtraction) + inline Num i32_sub(const Num &other) const { + uint32_t result_u = this->toUInt() - other.toUInt(); + return Num(static_cast(result_u)); + } + + // i32.mul (Wrapping multiplication) + inline Num i32_mul(const Num &other) const { + uint32_t result_u = this->toUInt() * other.toUInt(); + return Num(static_cast(result_u)); + } + + // i32.div_s (Signed division with traps) + inline Num i32_div_s(const Num &other) const { + int32_t divisor = other.toInt(); + int32_t dividend = this->toInt(); + + if (divisor == 0) { + throw std::runtime_error("i32.div_s: Division by zero"); } - return Num(toInt() / other.toInt()); + + return Num(dividend / divisor); + } + + // i32.shl (Shift Left): *this << other (shift count masked by 31) + inline Num i32_shl(const Num &other) const { + uint32_t shift_amount = other.toUInt() & 0x1F; + uint32_t result_u = toUInt() << shift_amount; + return Num(static_cast(result_u)); + } + + // i32.shr_s (Signed Shift Right): *this >> other (Arithmetic shift) + inline Num i32_shr_s(const Num &other) const { + // Wasm masks the shift amount by 31 (0x1F) + uint32_t shift_amount = other.toUInt() & 0x1F; + int32_t result_s = toInt() >> shift_amount; + return Num(result_s); } - Num operator<(const Num &other) const { return Num(toInt() < other.toInt()); } - Num operator<=(const Num &other) const { - return Num(toInt() <= other.toInt()); + + // i32.shr_u (Unsigned Shift Right): *this >>> other (Logical shift) + inline Num i32_shr_u(const Num &other) const { + // Wasm masks the shift amount by 31 (0x1F) + uint32_t shift_amount = other.toUInt() & 0x1F; + uint32_t result_u = toUInt() >> shift_amount; + return Num(static_cast(result_u)); } - Num operator>(const Num &other) const { return Num(toInt() > other.toInt()); } - Num operator>=(const Num &other) const { - return Num(toInt() >= other.toInt()); + + // i32.and (Bitwise AND) + inline Num i32_and(const Num &other) const { + uint32_t result_u = this->toUInt() & other.toUInt(); + return Num(static_cast(result_u)); } - Num operator&(const Num &other) const { return Num(toInt() & other.toInt()); } }; static Num I32V(int v) { return v; } @@ -303,6 +394,7 @@ struct Memory_t { } }; + static Memory_t Memory(1); // 1 page memory #endif // WASM_CONCRETE_RT_HPP \ No newline at end of file diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index fe268ed5..43e99131 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -1251,29 +1251,75 @@ static EvalRes eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { auto rhs_res = eval_sym_expr(operation->rhs, sym_env); auto lhs = lhs_res.value; auto rhs = rhs_res.value; + auto lhs_width = lhs_res.width; + auto rhs_width = rhs_res.width; switch (operation->op) { case ADD: - return EvalRes(lhs + rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_add(rhs), 32); + } else { + assert(false && "TODO"); + } case SUB: - return EvalRes(lhs - rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_sub(rhs), 32); + } else { + assert(false && "TODO"); + } case MUL: - return EvalRes(lhs * rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_mul(rhs), 32); + } else { + assert(false && "TODO"); + } case DIV: - return EvalRes(lhs / rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_div_s(rhs), 32); + } else { + assert(false && "TODO"); + } case LT: - return EvalRes(lhs < rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_lt_s(rhs), 32); + } else { + assert(false && "TODO"); + } case LEQ: - return EvalRes(lhs <= rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_le_s(rhs), 32); + } else { + assert(false && "TODO"); + } case GT: - return EvalRes(lhs > rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_gt_s(rhs), 32); + } else { + assert(false && "TODO"); + } case GEQ: - return EvalRes(lhs >= rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_ge_s(rhs), 32); + } else { + assert(false && "TODO"); + } case NEQ: - return EvalRes(lhs != rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_ne(rhs), 32); + } else { + assert(false && "TODO"); + } case EQ: - return EvalRes(lhs == rhs, 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_eq(rhs), 32); + } else { + assert(false && "TODO"); + } case B_AND: - return EvalRes(Num(I64V(lhs.value & rhs.value)), 32); + if (lhs_width == 32 && rhs_width == 32) { + return EvalRes(lhs.i32_and(rhs), 32); + } else { + assert(false && "TODO"); + } case CONCAT: { auto lhs_width = lhs_res.width; auto rhs_width = rhs_res.width; diff --git a/src/main/scala/wasm/StagedConcolicMiniWasm.scala b/src/main/scala/wasm/StagedConcolicMiniWasm.scala index aebf11ac..48d90280 100644 --- a/src/main/scala/wasm/StagedConcolicMiniWasm.scala +++ b/src/main/scala/wasm/StagedConcolicMiniWasm.scala @@ -581,7 +581,7 @@ trait StagedWasmEvaluator extends SAIOps { val s = Stack.popS(condTy) runtimeSymAssert(s) runtimeAssert(v.toInt != 0) - eval(rest, kont, mkont, trail)(ctx.pop()._2) + eval(rest, kont, mkont, trail)(newCtx) case Import(m, f, _) => throw new Exception(s"Unknown import $m.$f at $funcIndex") case _ => throw new Exception(s"Definition at $funcIndex is not callable") } @@ -667,8 +667,6 @@ trait StagedWasmEvaluator extends SAIOps { def evalTop(mkont: Rep[MCont[Unit]], main: Option[String]): Rep[Unit] = { Counter.reset() - Predef.println("[DEBUG]" + module) - Predef.println("[DEBUG] module.defs: " + module.defs) val funBody: FuncBodyDef = main match { case Some(func_name) => module.defs.flatMap({ @@ -1096,9 +1094,9 @@ trait StagedWasmEvaluator extends SAIOps { def <(rhs: StagedConcreteNum): StagedConcreteNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedConcreteNum(NumType(I32Type), "relation-lt".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-lts".reflectCtrlWith[Num](num.i, rhs.i)) case (NumType(I64Type), NumType(I64Type)) => - StagedConcreteNum(NumType(I32Type), "relation-lt".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-lts".reflectCtrlWith[Num](num.i, rhs.i)) } } @@ -1132,9 +1130,9 @@ trait StagedWasmEvaluator extends SAIOps { def <=(rhs: StagedConcreteNum): StagedConcreteNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedConcreteNum(NumType(I32Type), "relation-le".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-les".reflectCtrlWith[Num](num.i, rhs.i)) case (NumType(I64Type), NumType(I64Type)) => - StagedConcreteNum(NumType(I32Type), "relation-le".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-les".reflectCtrlWith[Num](num.i, rhs.i)) } } @@ -1150,9 +1148,9 @@ trait StagedWasmEvaluator extends SAIOps { def >=(rhs: StagedConcreteNum): StagedConcreteNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedConcreteNum(NumType(I32Type), "relation-ge".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-ges".reflectCtrlWith[Num](num.i, rhs.i)) case (NumType(I64Type), NumType(I64Type)) => - StagedConcreteNum(NumType(I32Type), "relation-ge".reflectCtrlWith[Num](num.i, rhs.i)) + StagedConcreteNum(NumType(I32Type), "relation-ges".reflectCtrlWith[Num](num.i, rhs.i)) } } @@ -1303,9 +1301,9 @@ trait StagedWasmEvaluator extends SAIOps { def <(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-lt".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-lts".reflectCtrlWith[SymVal](num.s, rhs.s)) case (NumType(I64Type), NumType(I64Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-lt".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-lts".reflectCtrlWith[SymVal](num.s, rhs.s)) } } @@ -1339,9 +1337,9 @@ trait StagedWasmEvaluator extends SAIOps { def <=(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-le".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-les".reflectCtrlWith[SymVal](num.s, rhs.s)) case (NumType(I64Type), NumType(I64Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-le".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-les".reflectCtrlWith[SymVal](num.s, rhs.s)) } } @@ -1357,9 +1355,9 @@ trait StagedWasmEvaluator extends SAIOps { def >=(rhs: StagedSymbolicNum): StagedSymbolicNum = { (num.tipe, rhs.tipe) match { case (NumType(I32Type), NumType(I32Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-ge".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-ges".reflectCtrlWith[SymVal](num.s, rhs.s)) case (NumType(I64Type), NumType(I64Type)) => - StagedSymbolicNum(NumType(I32Type), "sym-relation-ge".reflectCtrlWith[SymVal](num.s, rhs.s)) + StagedSymbolicNum(NumType(I32Type), "sym-relation-ges".reflectCtrlWith[SymVal](num.s, rhs.s)) } } @@ -1516,40 +1514,39 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { case Node(_, "sym-is-zero", List(s_num), _) => shallow(s_num); emit(".is_zero()") case Node(_, "binary-add", List(lhs, rhs), _) => - shallow(lhs); emit(" + "); shallow(rhs) + shallow(lhs); emit(".i32_add("); shallow(rhs); emit(")") case Node(_, "binary-sub", List(lhs, rhs), _) => - // todo: avoid using c++ operator, use explicit method call so operator's precedence issues won't exist - emit("("); shallow(lhs); emit(" - "); shallow(rhs); emit(")") + shallow(lhs); emit(".i32_sub("); shallow(rhs); emit(")") case Node(_, "binary-mul", List(lhs, rhs), _) => - shallow(lhs); emit(" * "); shallow(rhs) + shallow(lhs); emit(".i32_mul("); shallow(rhs); emit(")") case Node(_, "binary-div", List(lhs, rhs), _) => - shallow(lhs); emit(" / "); shallow(rhs) + shallow(lhs); emit(".i32_div_s("); shallow(rhs); emit(")") case Node(_, "binary-shl", List(lhs, rhs), _) => - shallow(lhs); emit(" << "); shallow(rhs) + shallow(lhs); emit(".i32_shl("); shallow(rhs); emit(")") case Node(_, "binary-shr", List(lhs, rhs), _) => - shallow(lhs); emit(" >> "); shallow(rhs) + shallow(lhs); emit(".i32_shr("); shallow(rhs); emit(")") case Node(_, "binary-and", List(lhs, rhs), _) => - shallow(lhs); emit(" & "); shallow(rhs) + shallow(lhs); emit(".i32_and("); shallow(rhs); emit(")") case Node(_, "relation-eq", List(lhs, rhs), _) => - shallow(lhs); emit(" == "); shallow(rhs) + shallow(lhs); emit(".i32_eq("); shallow(rhs); emit(")") case Node(_, "relation-ne", List(lhs, rhs), _) => - shallow(lhs); emit(" != "); shallow(rhs) - case Node(_, "relation-lt", List(lhs, rhs), _) => - shallow(lhs); emit(" < "); shallow(rhs) + shallow(lhs); emit(".i32_ne("); shallow(rhs); emit(")") + case Node(_, "relation-lts", List(lhs, rhs), _) => + shallow(lhs); emit(".i32_lt_s("); shallow(rhs); emit(")") case Node(_, "relation-ltu", List(lhs, rhs), _) => - shallow(lhs); emit(" < "); shallow(rhs) + shallow(lhs); emit(".i32_lt_u("); shallow(rhs); emit(")") case Node(_, "relation-gt", List(lhs, rhs), _) => - shallow(lhs); emit(" > "); shallow(rhs) + shallow(lhs); emit(".i32_gt_s("); shallow(rhs); emit(")") case Node(_, "relation-gtu", List(lhs, rhs), _) => - shallow(lhs); emit(" > "); shallow(rhs) - case Node(_, "relation-le", List(lhs, rhs), _) => - shallow(lhs); emit(" <= "); shallow(rhs) + shallow(lhs); emit(".i32_gt_u("); shallow(rhs); emit(")") + case Node(_, "relation-les", List(lhs, rhs), _) => + shallow(lhs); emit(".i32_le_s("); shallow(rhs); emit(")") case Node(_, "relation-leu", List(lhs, rhs), _) => - shallow(lhs); emit(" <= "); shallow(rhs) - case Node(_, "relation-ge", List(lhs, rhs), _) => - shallow(lhs); emit(" >= "); shallow(rhs) + shallow(lhs); emit(".i32_le_u("); shallow(rhs); emit(")") + case Node(_, "relation-ges", List(lhs, rhs), _) => + shallow(lhs); emit(".i32_ge_s("); shallow(rhs); emit(")") case Node(_, "relation-geu", List(lhs, rhs), _) => - shallow(lhs); emit(" >= "); shallow(rhs) + shallow(lhs); emit(".i32_ge_u("); shallow(rhs); emit(")") case Node(_, "sym-binary-add", List(lhs, rhs), _) => shallow(lhs); emit(".add("); shallow(rhs); emit(")") case Node(_, "sym-binary-sub", List(lhs, rhs), _) => @@ -1560,13 +1557,13 @@ trait StagedWasmCppGen extends CGenBase with CppSAICodeGenBase { shallow(lhs); emit(".div("); shallow(rhs); emit(")") case Node(_, "sym-binary-and", List(lhs, rhs), _) => shallow(lhs); emit(".bitwise_and("); shallow(rhs); emit(")") - case Node(_, "sym-relation-le", List(lhs, rhs), _) => + case Node(_, "sym-relation-les", List(lhs, rhs), _) => shallow(lhs); emit(".le("); shallow(rhs); emit(")") case Node(_, "sym-relation-leu", List(lhs, rhs), _) => shallow(lhs); emit(".leu("); shallow(rhs); emit(")") - case Node(_, "sym-relation-lt", List(lhs, rhs), _) => + case Node(_, "sym-relation-lts", List(lhs, rhs), _) => shallow(lhs); emit(".lt("); shallow(rhs); emit(")") - case Node(_, "sym-relation-ge", List(lhs, rhs), _) => + case Node(_, "sym-relation-ges", List(lhs, rhs), _) => shallow(lhs); emit(".ge("); shallow(rhs); emit(")") case Node(_, "sym-relation-geu", List(lhs, rhs), _) => shallow(lhs); emit(".geu("); shallow(rhs); emit(")") From 0552131a7929ba2e1b0875c10c2f1d555680f81f Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Thu, 6 Nov 2025 22:40:13 -0500 Subject: [PATCH 79/82] fixed a bug, zero initialize local variables --- headers/wasm/concolic_driver.hpp | 17 +++++- headers/wasm/concrete_rt.hpp | 92 +++++++++++++++++++++++++------- headers/wasm/symbolic_rt.hpp | 5 ++ 3 files changed, 93 insertions(+), 21 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index 7211a5a2..e9da77c1 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -3,11 +3,11 @@ #include "concrete_rt.hpp" #include "config.hpp" +#include "output_report.hpp" #include "profile.hpp" #include "smt_solver.hpp" #include "symbolic_rt.hpp" #include "utils.hpp" -#include "output_report.hpp" #include #include #include @@ -103,13 +103,26 @@ inline void ConcolicDriver::main_exploration_loop() { try { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); - { node->reach_here(entrypoint); } + if (REUSE_SNAPSHOT) { + node->reach_here(entrypoint); + } else { + auto timer = ManagedTimer(TimeProfileKind::INSTR); + ExploreTree.reset_cursor(); + reset_stacks(); + entrypoint(); + } GENSYM_INFO("Execution finished successfully with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); } catch (std::runtime_error &e) { std::cout << "Caught runtime error: " << e.what() << std::endl; ExploreTree.fillFailedNode(); + + if (std::string(e.what()) == "Symbolic assertion failed") { + GENSYM_INFO("Symbolic assertion failed, continuing to next path..."); + continue; + } + GENSYM_INFO("Caught runtime error with symbolic environment:"); GENSYM_INFO(SymEnv.to_string()); switch (EXPLORE_MODE) { diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index a63d2d7e..4a2d4ad5 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -21,75 +21,115 @@ struct Num { int32_t toInt() const { return static_cast(value); } uint32_t toUInt() const { return static_cast(value); } + // debug printer: enabled only when -DDEBUG + static inline void debug_print(const char *op, const Num &a, const Num &b, + const Num &res) { +#ifdef DEBUG_OP + std::cout << "[Debug] " << op << ": lhs=" << static_cast(a.value) + << " rhs=" << static_cast(b.value) + << " -> res=" << static_cast(res.value) << std::endl; +#endif + } + // Helper to create a Wasm Boolean result (1 or 0 as Num) - Num WasmBool(bool condition) const { return Num(condition ? 1 : 0); } + Num WasmBool(bool condition) const { + Num res(condition ? 1 : 0); + debug_print("WasmBool", *this, *this, res); + return res; + } // TODO: support different bit width operations, for now we just assume all // oprands are i32 // i32.eq (Equals): *this == other inline Num i32_eq(const Num &other) const { - return WasmBool(this->toUInt() == other.toUInt()); + Num res = WasmBool(this->toUInt() == other.toUInt()); + debug_print("i32.eq", *this, other, res); + return res; } // i32.ne (Not Equals): *this != other inline Num i32_ne(const Num &other) const { - return WasmBool(this->toUInt() != other.toUInt()); + Num res = WasmBool(this->toUInt() != other.toUInt()); + debug_print("i32.ne", *this, other, res); + return res; } // i32.lt_s (Signed Less Than): *this < other inline Num i32_lt_s(const Num &other) const { - return WasmBool(this->toInt() < other.toInt()); + Num res = WasmBool(this->toInt() < other.toInt()); + debug_print("i32.lt_s", *this, other, res); + return res; } // i32.lt_u (Unsigned Less Than): *this < other (unsigned) inline Num i32_lt_u(const Num &other) const { - return WasmBool(this->toUInt() < other.toUInt()); + Num res = WasmBool(this->toUInt() < other.toUInt()); + debug_print("i32.lt_u", *this, other, res); + return res; } // i32.le_s (Signed Less Than or Equal): *this <= other inline Num i32_le_s(const Num &other) const { - return WasmBool(this->toInt() <= other.toInt()); + Num res = WasmBool(this->toInt() <= other.toInt()); + debug_print("i32.le_s", *this, other, res); + return res; } // i32.le_u (Unsigned Less Than or Equal): *this <= other (unsigned) inline Num i32_le_u(const Num &other) const { - return WasmBool(this->toUInt() <= other.toUInt()); + Num res = WasmBool(this->toUInt() <= other.toUInt()); + debug_print("i32.le_u", *this, other, res); + return res; } // i32.gt_s (Signed Greater Than): *this > other inline Num i32_gt_s(const Num &other) const { - return WasmBool(this->toInt() > other.toInt()); + Num res = WasmBool(this->toInt() > other.toInt()); + debug_print("i32.gt_s", *this, other, res); + return res; } // i32.gt_u (Unsigned Greater Than): *this > other (unsigned) inline Num i32_gt_u(const Num &other) const { - return WasmBool(this->toUInt() > other.toUInt()); + Num res = WasmBool(this->toUInt() > other.toUInt()); + debug_print("i32.gt_u", *this, other, res); + return res; } // i32.ge_s (Signed Greater Than or Equal): *this >= other inline Num i32_ge_s(const Num &other) const { - return WasmBool(this->toInt() >= other.toInt()); + Num res = WasmBool(this->toInt() >= other.toInt()); + debug_print("i32.ge_s", *this, other, res); + return res; } // i32.ge_u (Unsigned Greater Than or Equal): *this >= other (unsigned) inline Num i32_ge_u(const Num &other) const { - return WasmBool(this->toUInt() >= other.toUInt()); + Num res = WasmBool(this->toUInt() >= other.toUInt()); + debug_print("i32.ge_u", *this, other, res); + return res; } // i32.add (Wrapping addition) inline Num i32_add(const Num &other) const { uint32_t result_u = this->toUInt() + other.toUInt(); - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.add", *this, other, res); + return res; } // i32.sub (Wrapping subtraction) inline Num i32_sub(const Num &other) const { uint32_t result_u = this->toUInt() - other.toUInt(); - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.sub", *this, other, res); + return res; } // i32.mul (Wrapping multiplication) inline Num i32_mul(const Num &other) const { uint32_t result_u = this->toUInt() * other.toUInt(); - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.mul", *this, other, res); + return res; } // i32.div_s (Signed division with traps) @@ -101,14 +141,18 @@ struct Num { throw std::runtime_error("i32.div_s: Division by zero"); } - return Num(dividend / divisor); + Num res(dividend / divisor); + debug_print("i32.div_s", *this, other, res); + return res; } // i32.shl (Shift Left): *this << other (shift count masked by 31) inline Num i32_shl(const Num &other) const { uint32_t shift_amount = other.toUInt() & 0x1F; uint32_t result_u = toUInt() << shift_amount; - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.shl", *this, other, res); + return res; } // i32.shr_s (Signed Shift Right): *this >> other (Arithmetic shift) @@ -116,7 +160,9 @@ struct Num { // Wasm masks the shift amount by 31 (0x1F) uint32_t shift_amount = other.toUInt() & 0x1F; int32_t result_s = toInt() >> shift_amount; - return Num(result_s); + Num res(result_s); + debug_print("i32.shr_s", *this, other, res); + return res; } // i32.shr_u (Unsigned Shift Right): *this >>> other (Logical shift) @@ -124,13 +170,17 @@ struct Num { // Wasm masks the shift amount by 31 (0x1F) uint32_t shift_amount = other.toUInt() & 0x1F; uint32_t result_u = toUInt() >> shift_amount; - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.shr_u", *this, other, res); + return res; } // i32.and (Bitwise AND) inline Num i32_and(const Num &other) const { uint32_t result_u = this->toUInt() & other.toUInt(); - return Num(static_cast(result_u)); + Num res(static_cast(result_u)); + debug_print("i32.and", *this, other, res); + return res; } }; @@ -272,6 +322,10 @@ class Frames_t { void pushFrame(std::int32_t size) { assert(size >= 0); count += size; + // Zero-initialize the new stack frames. + for (std::int32_t i = 0; i < size; ++i) { + stack_ptr[count - 1 - i] = Num(0); + } } void reset() { count = 0; } diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index 43e99131..f5177657 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -777,7 +777,12 @@ inline bool NodeBox::fillIfElseNode(SymVal cond, int id) { } else if (dynamic_cast(node.get())) { node = std::make_unique(cond, this, id); return true; + } else if (dynamic_cast(node.get()) != nullptr) { + assert(false && + "Unexpected traversal: arrived at a node marked 'NotToExplore'."); + return false; } + assert( dynamic_cast(node.get()) != nullptr && "Current node is not an Unexplored nor an IfElseNode, cannot fill it!"); From 6744d1807c20f762f743a2ace57c1db0cf5d9a02 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 8 Nov 2025 16:45:27 -0500 Subject: [PATCH 80/82] use z3's api to evaluate a symbolic expression --- headers/wasm/concolic_driver.hpp | 16 +++- headers/wasm/smt_solver.hpp | 22 +++-- headers/wasm/symbolic_rt.hpp | 148 ++++++++++++++++++++++++------- 3 files changed, 146 insertions(+), 40 deletions(-) diff --git a/headers/wasm/concolic_driver.hpp b/headers/wasm/concolic_driver.hpp index e9da77c1..cb3a40c0 100644 --- a/headers/wasm/concolic_driver.hpp +++ b/headers/wasm/concolic_driver.hpp @@ -96,7 +96,8 @@ inline void ConcolicDriver::main_exploration_loop() { node->fillUnreachableNode(); continue; } - auto new_env = result.value(); + auto &new_env = result.value().first; + auto &model = result.value().second; // update global symbolic environment from SMT solved model SymEnv.update(std::move(new_env)); @@ -104,7 +105,18 @@ inline void ConcolicDriver::main_exploration_loop() { GENSYM_INFO("Now execute the program with symbolic environment: "); GENSYM_INFO(SymEnv.to_string()); if (REUSE_SNAPSHOT) { - node->reach_here(entrypoint); + if (auto snapshot = dynamic_cast(node->node.get())) { + assert(REUSE_SNAPSHOT); + auto snap = snapshot->get_snapshot(); + std::cout << "Model \n" + << model << std::endl; + snap.resume_execution_by_model(node, model); + } else { + auto timer = ManagedTimer(TimeProfileKind::INSTR); + ExploreTree.reset_cursor(); + reset_stacks(); + entrypoint(); + } } else { auto timer = ManagedTimer(TimeProfileKind::INSTR); ExploreTree.reset_cursor(); diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index 09c91e89..e94e0ee1 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -17,7 +17,8 @@ class Solver { public: Solver() {} - std::optional solve(std::vector &conditions) { + std::optional> + solve(std::vector &conditions) { z3::solver z3_solver(z3_ctx); z3::check_result solver_result; { @@ -50,13 +51,15 @@ class Solver { GENSYM_INFO("Find a variable that is not created by GenSym: " + name); } } - return result; + return std::optional>( + std::in_place, std::move(result), std::move(model)); } case z3::unknown: throw std::runtime_error("Z3 solver returned unknown status"); } return std::nullopt; // Should not reach here } + z3::expr build_z3_expr(SymVal &sym_val); private: z3::expr to_z3_conjunction(std::vector &conditions) { @@ -73,7 +76,6 @@ class Solver { } z3::context z3_ctx; - z3::expr build_z3_expr(SymVal &sym_val); z3::expr build_z3_expr_aux(SymVal &sym_val); }; @@ -158,14 +160,22 @@ inline z3::expr Solver::build_z3_expr_aux(SymVal &sym_val) { } inline z3::expr Solver::build_z3_expr(SymVal &sym_val) { - if (sym_val.z3_expr) { - return *sym_val.z3_expr; + if (sym_val.symptr->z3_expr()) { + return *sym_val.symptr->z3_expr(); } auto e = build_z3_expr_aux(sym_val); - sym_val.z3_expr = std::make_shared(e); + sym_val.symptr->update_z3_expr(e); return e; } +inline EvalRes eval_sym_expr_by_model(const SymVal &sym, z3::model &model) { + auto expr = solver.build_z3_expr(const_cast(sym)); + z3::expr value = model.eval(expr, false); + // every value is bitvector + int width = expr.get_sort().bv_size(); + return EvalRes(Num(value.get_numeral_int64()), width); +} + inline std::monostate GENSYM_SYM_ASSERT(SymVal &sym_cond) { std::vector conds = ExploreTree.collect_current_path_conds(); conds.push_back(sym_cond.negate()); diff --git a/headers/wasm/symbolic_rt.hpp b/headers/wasm/symbolic_rt.hpp index f5177657..fefc126b 100644 --- a/headers/wasm/symbolic_rt.hpp +++ b/headers/wasm/symbolic_rt.hpp @@ -32,6 +32,11 @@ class Symbolic { Symbolic() {} virtual ~Symbolic() = default; // Make Symbolic polymorphic virtual int size() = 0; + virtual std::optional z3_expr() { return _z3_expr; } + virtual void update_z3_expr(z3::expr expr) { _z3_expr = expr; } + +private: + std::optional _z3_expr; }; static int max_id = 0; @@ -91,7 +96,6 @@ static std::shared_ptr ZeroByte = struct SymVal { std::shared_ptr symptr; - std::shared_ptr z3_expr; SymVal() : symptr(ZERO) {} SymVal(std::shared_ptr symptr) : symptr(symptr) {} @@ -147,20 +151,34 @@ struct SymExtract : Symbolic { SymVal value; int high; int low; + int size_cache = -1; SymExtract(SymVal value, int high, int low) : value(value), high(high), low(low) {} - int size() override { return 1 + value.size(); } + int size() override { + if (size_cache != -1) { + return size_cache; + } + size_cache = 1 + value.size(); + return size_cache; + } }; struct SymBinary : Symbolic { Operation op; SymVal lhs; SymVal rhs; + int size_cache = -1; SymBinary(Operation op, SymVal lhs, SymVal rhs) : op(op), lhs(lhs), rhs(rhs) {} - int size() override { return 1 + lhs.size() + rhs.size(); } + int size() override { + if (size_cache != -1) { + return size_cache; + } + size_cache = 1 + lhs.size() + rhs.size(); + return size_cache; + } }; inline SymVal SymVal::add(const SymVal &other) const { @@ -517,6 +535,8 @@ class Snapshot_t { SymMemory_t get_memory() const { return memory; } std::monostate resume_execution(NodeBox *node) const; + std::monostate resume_execution_by_model(NodeBox *node, + z3::model &model) const; static int cost_of_snapshot(); @@ -527,6 +547,7 @@ class Snapshot_t { // The continuation at the snapshot point Cont_t cont; MCont_t mcont; + void restore_states_to_global() const; }; static SymFrames_t SymFrames; @@ -899,7 +920,10 @@ inline int Snapshot_t::cost_of_snapshot() { auto cost_of_stack_copy = SymStack.cost_of_copy(); auto cost_of_frame_copy = SymFrames.cost_of_copy(); auto cost_of_memory_copy = SymMemory.cost_of_copy(); - return 5.336 * + // The speed ratio between symbolic expression instantiation and WebAssembly + // instruction execution, given by benchmark results + auto ratio = 5.336; + return ratio * (cost_of_stack_copy + cost_of_frame_copy + cost_of_memory_copy); } @@ -968,22 +992,16 @@ class ExploreTree_t { bool worth_to_create_snapshot() { if (!ENABLE_COST_MODEL) { + // If we are not using cost model, always create snapshot return REUSE_SNAPSHOT; } // find out the best way to reach the current position via our cost model auto snapshot_cost = Snapshot_t::cost_of_snapshot(); - int reach_parent_cost = 0; - if (cursor->parent) { - reach_parent_cost = cursor->parent->min_cost_of_reaching_here(); - } else { - reach_parent_cost = 0; + int re_execution_cost = cursor->instr_cost; + if (snapshot_cost <= re_execution_cost) { + GENSYM_INFO("Snapshot is worth to create"); } - auto parent_cost = - cursor->parent ? cursor->parent->min_cost_of_reaching_here() : 0; - auto exec_from_parent_cost = reach_parent_cost + cursor->instr_cost; - GENSYM_INFO("The score of snapshot tendency: " + - std::to_string(exec_from_parent_cost - snapshot_cost)); - return snapshot_cost <= exec_from_parent_cost; + return snapshot_cost <= re_execution_cost; } std::monostate moveCursor(bool branch, Control control) { @@ -994,7 +1012,9 @@ class ExploreTree_t { if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); int cost_from_parent = CostManager.dump_instr_cost(); - cursor->instr_cost = cost_from_parent; + int cost_from_root = + cost_from_parent + (cursor->parent ? cursor->parent->instr_cost : 0); + cursor->instr_cost = cost_from_root; if (branch) { true_branch_cov_map[if_else_node->id] = true; if (worth_to_create_snapshot()) { @@ -1026,7 +1046,9 @@ class ExploreTree_t { if_else_node != nullptr && "Can't move cursor when the branch node is not initialized correctly!"); int cost_from_parent = CostManager.dump_instr_cost(); - cursor->instr_cost = cost_from_parent; + int cost_from_root = + cost_from_parent + (cursor->parent ? cursor->parent->instr_cost : 0); + cursor->instr_cost = cost_from_root; if (branch) { true_branch_cov_map[if_else_node->id] = true; if_else_node->false_branch->fillNotToExploreNode(); @@ -1343,6 +1365,8 @@ static EvalRes eval_sym_expr(const SymVal &sym, SymEnv_t &sym_env) { throw std::runtime_error("Not supported symbolic expression"); } +inline EvalRes eval_sym_expr_by_model(const SymVal &sym, z3::model &model); + static void resume_conc_stack(const SymStack_t &sym_stack, Stack_t &stack, SymEnv_t &sym_env) { stack.resize(sym_stack.size()); @@ -1354,8 +1378,21 @@ static void resume_conc_stack(const SymStack_t &sym_stack, Stack_t &stack, } } +static void resume_conc_stack_by_model(const SymStack_t &sym_stack, + Stack_t &stack, z3::model &model) { + GENSYM_INFO("Restoring concrete stack from symbolic stack"); + stack.resize(sym_stack.size()); + for (size_t i = 0; i < sym_stack.size(); ++i) { + auto sym = sym_stack[i]; + auto res = eval_sym_expr_by_model(sym, model); + auto conc = res.value; + stack.set_from_front(i, conc); + } +} + static void resume_conc_frames(const SymFrames_t &sym_frame, Frames_t &frames, SymEnv_t &sym_env) { + GENSYM_INFO("Restoring concrete frames from symbolic frames"); frames.resize(sym_frame.size()); for (size_t i = 0; i < sym_frame.size(); ++i) { auto sym = sym_frame[i]; @@ -1366,8 +1403,22 @@ static void resume_conc_frames(const SymFrames_t &sym_frame, Frames_t &frames, } } +static void resume_conc_frames_by_model(const SymFrames_t &sym_frame, + Frames_t &frames, z3::model &model) { + GENSYM_INFO("Restoring concrete frames from symbolic frames"); + frames.resize(sym_frame.size()); + for (size_t i = 0; i < sym_frame.size(); ++i) { + auto sym = sym_frame[i]; + assert(sym.symptr != nullptr); + auto res = eval_sym_expr_by_model(sym, model); + auto conc = res.value; + frames.set_from_front(i, conc); + } +} + static void resume_conc_memory(const SymMemory_t &sym_memory, Memory_t &memory, SymEnv_t &sym_env) { + GENSYM_INFO("Restoring concrete memory from symbolic memory"); memory.reset(); for (const auto &pair : sym_memory.memory) { int32_t addr = pair.first; @@ -1380,6 +1431,21 @@ static void resume_conc_memory(const SymMemory_t &sym_memory, Memory_t &memory, } } +static void resume_conc_memory_by_model(const SymMemory_t &sym_memory, + Memory_t &memory, z3::model &model) { + GENSYM_INFO("Restoring concrete memory from symbolic memory"); + memory.reset(); + for (const auto &pair : sym_memory.memory) { + int32_t addr = pair.first; + SymVal sym = pair.second; + assert(sym.symptr != nullptr); + auto res = eval_sym_expr_by_model(sym, model); + auto conc = res.value; + assert(res.width == 8 && "Memory should only store bytes"); + memory.store_byte(addr, conc.value & 0xFF); + } +} + static void resume_conc_states(const SymStack_t &sym_stack, const SymFrames_t &sym_frame, const SymMemory_t &sym_memory, Stack_t &stack, @@ -1390,33 +1456,51 @@ static void resume_conc_states(const SymStack_t &sym_stack, resume_conc_memory(sym_memory, memory, sym_env); } -inline std::monostate Snapshot_t::resume_execution(NodeBox *node) const { - // Reset explore tree's cursor - ExploreTree.set_cursor(node); +static void resume_conc_states_by_model(const SymStack_t &sym_stack, + const SymFrames_t &sym_frame, + const SymMemory_t &sym_memory, + Stack_t &stack, Frames_t &frames, + Memory_t &memory, z3::model &model) { + resume_conc_stack_by_model(sym_stack, stack, model); + resume_conc_frames_by_model(sym_frame, frames, model); + resume_conc_memory_by_model(sym_memory, memory, model); +} +inline void Snapshot_t::restore_states_to_global() const { // Restore the symbolic state from the snapshot GENSYM_INFO("Reusing symbolic state from snapshot"); SymStack = stack; SymFrames = frames; SymMemory = memory; +} + +inline std::monostate +Snapshot_t::resume_execution_by_model(NodeBox *node, z3::model &model) const { + // Reset explore tree's cursor and restore symbolic states + ExploreTree.set_cursor(node); + restore_states_to_global(); + { auto timer = ManagedTimer(TimeProfileKind::RESUME_SNAPSHOT); // Restore the concrete states from the symbolic states - resume_conc_states(stack, frames, memory, Stack, Frames, Memory, SymEnv); + resume_conc_states_by_model(stack, frames, memory, Stack, Frames, Memory, + model); } - int sym_size = 0; + // Resume execution from the continuation + auto timer = ManagedTimer(TimeProfileKind::INSTR); + return cont(mcont); +} + +[[deprecated]] +inline std::monostate Snapshot_t::resume_execution(NodeBox *node) const { + // Reset explore tree's cursor and restore symbolic states + ExploreTree.set_cursor(node); + restore_states_to_global(); { - auto timer = ManagedTimer(TimeProfileKind::COUNT_SYM_SIZE); - for (size_t i = 0; i < stack.size(); ++i) { - sym_size += stack[i].size(); - } - for (size_t i = 0; i < frames.size(); ++i) { - sym_size += frames[i].size(); - } + auto timer = ManagedTimer(TimeProfileKind::RESUME_SNAPSHOT); + // Restore the concrete states from the symbolic states + resume_conc_states(stack, frames, memory, Stack, Frames, Memory, SymEnv); } - std::cout << "[Info] Resumed symbolic execution from snapshot, total " - "symbolic expression and frame size: " - << sym_size << std::endl; // Resume execution from the continuation auto timer = ManagedTimer(TimeProfileKind::INSTR); From 5f6566920e3c0b4801f27d6adae4f5acef2dd1a8 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 8 Nov 2025 16:58:04 -0500 Subject: [PATCH 81/82] let z3 decide the value of symbols that are not in the model --- headers/wasm/smt_solver.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/headers/wasm/smt_solver.hpp b/headers/wasm/smt_solver.hpp index e94e0ee1..a34ab6d3 100644 --- a/headers/wasm/smt_solver.hpp +++ b/headers/wasm/smt_solver.hpp @@ -170,7 +170,8 @@ inline z3::expr Solver::build_z3_expr(SymVal &sym_val) { inline EvalRes eval_sym_expr_by_model(const SymVal &sym, z3::model &model) { auto expr = solver.build_z3_expr(const_cast(sym)); - z3::expr value = model.eval(expr, false); + // let z3 decide the value of symbols that are not in the model + z3::expr value = model.eval(expr, true); // every value is bitvector int width = expr.get_sort().bv_size(); return EvalRes(Num(value.get_numeral_int64()), width); From 48948294026215b17ba265b31c9c6c848891c777 Mon Sep 17 00:00:00 2001 From: butterunderflow Date: Sat, 8 Nov 2025 17:10:47 -0500 Subject: [PATCH 82/82] tweak tests --- headers/wasm/concrete_rt.hpp | 1 + .../genwasym/TestStagedConcolicEval.scala | 25 ++++++++++++------- src/test/scala/genwasym/TestStagedEval.scala | 16 ++++++++---- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/headers/wasm/concrete_rt.hpp b/headers/wasm/concrete_rt.hpp index 4a2d4ad5..852570ef 100644 --- a/headers/wasm/concrete_rt.hpp +++ b/headers/wasm/concrete_rt.hpp @@ -265,6 +265,7 @@ class Stack_t { for (int32_t i = 0; i < count; ++i) { std::cout << stack_ptr[count - i - 1].value << std::endl; } + std::cout << "End of Stack contents" << std::endl; } void initialize() { diff --git a/src/test/scala/genwasym/TestStagedConcolicEval.scala b/src/test/scala/genwasym/TestStagedConcolicEval.scala index d1590f6a..f58f2c6b 100644 --- a/src/test/scala/genwasym/TestStagedConcolicEval.scala +++ b/src/test/scala/genwasym/TestStagedConcolicEval.scala @@ -73,11 +73,17 @@ class TestStagedConcolicEval extends FunSuite { println(result) expect.map(vs => { - val stackValues = result - .split("Stack contents: \n")(1) - .split("\n") - .map(_.toFloat) - .toList + val stackValues = { + val startMarker = "Stack contents: \n" + val endMarker = "End of Stack contents" + val start = result.indexOf(startMarker) + val end = if (start >= 0) result.indexOf(endMarker, start + startMarker.length) else -1 + require(start >= 0 && end >= 0, s"Could not find markers '$startMarker' and '$endMarker' in output") + result.substring(start + startMarker.length, end).trim + .split("\n") + .map(_.toFloat) + .toList + } assert(vs == stackValues) }) } @@ -113,10 +119,11 @@ class TestStagedConcolicEval extends FunSuite { } test("btree-bug-finding-concolic") { testFileConcolicCpp("./benchmarks/wasm/btree/2o1u-unlabeled.wat", exitByCoverage = true) } - test("long-trivial-execution-concrete") { - // This is a example to show how much performance improvement we can get by immutable data structure - testFileConcreteCpp("./benchmarks/wasm/staged/long-trivial-execution.wat", None) - } + // Don't run this test by default since it takes too long and is only for performance comparison + // test("long-trivial-execution-concrete") { + // // This is a example to show how much performance improvement we can get by immutable data structure + // testFileConcreteCpp("./benchmarks/wasm/staged/long-trivial-execution.wat", None) + // } test("return-poly - concrete") { testFileConcreteCpp("./benchmarks/wasm/staged/return_poly.wat", Some("$real_main"), expect=Some(List(42))) diff --git a/src/test/scala/genwasym/TestStagedEval.scala b/src/test/scala/genwasym/TestStagedEval.scala index 3769428f..ec7c43be 100644 --- a/src/test/scala/genwasym/TestStagedEval.scala +++ b/src/test/scala/genwasym/TestStagedEval.scala @@ -36,11 +36,17 @@ class TestStagedEval extends FunSuite { println(result) expect.map(vs => { - val stackValues = result - .split("Stack contents: \n")(1) - .split("\n") - .map(_.toFloat) - .toList + val stackValues = { + val startMarker = "Stack contents: \n" + val endMarker = "End of Stack contents" + val start = result.indexOf(startMarker) + val end = if (start >= 0) result.indexOf(endMarker, start + startMarker.length) else -1 + require(start >= 0 && end >= 0, s"Could not find markers '$startMarker' and '$endMarker' in output") + result.substring(start + startMarker.length, end).trim + .split("\n") + .map(_.toFloat) + .toList + } assert(vs == stackValues) }) }