diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Ctx.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Ctx.scala index b94858d368..bac8355032 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Ctx.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Ctx.scala @@ -8,10 +8,11 @@ import hkmc2.utils.* import document.* import document.Document -import semantics.* +import semantics.*, Elaborator.State import text.Param as WasmParam import Instructions.* +import scala.annotation.nowarn import scala.collection.mutable.{ArrayBuffer as ArrayBuf, Map as MutMap} /** A Wasm function and its associated information. @@ -30,14 +31,17 @@ import scala.collection.mutable.{ArrayBuffer as ArrayBuf, Map as MutMap} * [[Seq]] of local variables (excluding parameters) and their names. * @param body * The expression of the function body. + * @param exports + * Optional export name for the function. */ class FuncInfo( - val id: Opt[SymIdx], + val id: SymIdx, val typeIdx: TypeIdx, params: Seq[Local -> Str], nResults: Int, locals: Seq[Local -> Str], val body: Expr, + val `export`: Opt[Str], ) extends ToWat: /** @param sym @@ -60,13 +64,33 @@ class FuncInfo( nResults: Int, locals: Seq[Local -> Str], body: Expr, - ) = this( - sym.optionIf(_.nameIsMeaningful).map(sym => SymIdx(sym.nme)), + )(using Raise, Scope) = this( + SymIdx(sym.optionIf(_.nameIsMeaningful).fold(summon[Scope].allocateName(sym))(_.nme)), typeIdx, params, nResults, locals, body, + sym.optionIf(_.nameIsMeaningful).map(_.nme), + ) + + @deprecated("Consider providing a symbolic identifier by using `Scope.allocateName` with a `TempSymbol`.") + def this( + id: Opt[SymIdx], + typeIdx: TypeIdx, + params: Seq[Local -> Str], + nResults: Int, + locals: Seq[Local -> Str], + body: Expr, + `export`: Opt[Str], + )(using Raise, Scope, State) = this( + id.getOrElse(SymIdx(summon[Scope].allocateName(TempSymbol(N, "")))), + typeIdx, + params, + nResults, + locals, + body, + `export`, ) /** Returns the type of this function as a [[SignatureType]]. */ @@ -76,16 +100,16 @@ class FuncInfo( ) def toWat: Document = - doc"""(func ${id.fold(doc"")(_.toWat)} (type ${typeIdx.toWat})${ + doc"""(func ${id.toWat} (type ${typeIdx.toWat})${ getSignatureType.toWat.surroundUnlessEmpty(doc" ") } #{ ${ locals.map: p => doc"(local $$${p._2} ${RefType.anyref.toWat})" .mkDocument(doc" # ").surroundUnlessEmpty(doc" # ") } # ${body.toWat} #} )${ - id.fold(doc""): id => - doc""" # (export "${id.id}" (func ${id.toWat})) # (elem declare func ${id.toWat})""" - }""" + `export`.fold(doc""): e => + doc""" # (export "${e}" (func ${id.toWat}))""" + } # (elem declare func ${id.toWat})""" end FuncInfo /** A Wasm global and its associated information. @@ -121,29 +145,33 @@ end GlobalInfo * Symbolic identifier for the function, or `N` if the function is anonymous. * @param compType * The composite type this type definition represents. + * @param objectTag + * An optional object tag number associated with this type. */ -class TypeInfo(val id: Opt[SymIdx], val compType: CompType) extends ToWat: +class TypeInfo(val id: SymIdx, val compType: CompType, val objectTag: Opt[Int]) extends ToWat: /** @param sym * The source [[BlockMemberSymbol]] which this type is generated from. * @param compType * The composite type this type definition represents. */ - def this(sym: BlockMemberSymbol, compType: CompType) = this( - sym.optionIf(_.nameIsMeaningful).map(sym => SymIdx(sym.nme)), + def this(sym: BlockMemberSymbol, compType: CompType, objectTag: Opt[Int])(using Raise, Scope) = this( + SymIdx(sym.optionIf(_.nameIsMeaningful).fold(summon[Scope].allocateName(sym))(_.nme)), compType, + objectTag, ) - private def idDoc: Document = id.fold(doc"")(_.toWat) + def this(id: Opt[SymIdx], compType: CompType)(using Raise, Scope, State) = + this(id.getOrElse(SymIdx(summon[Scope].allocateName(TempSymbol(N, "")))), compType, N) def toWat: Document = compType match case struct: StructType if struct.isSubtype => val parentsDoc = struct.parents.optionIf(_.nonEmpty).fold(doc""): parents => parents.map(_.toWat).mkDocument(doc" ") val structDoc = struct.copy(isSubtype = false).toWat - doc"(type${idDoc.surroundUnlessEmpty(doc" ")} (sub${parentsDoc.surroundUnlessEmpty(doc" ")} ${structDoc}))" + doc"(type ${id.toWat} (sub${parentsDoc.surroundUnlessEmpty(doc" ")} ${structDoc}))" case _ => - doc"(type${idDoc.surroundUnlessEmpty(doc" ")} ${compType.toWat})" + doc"(type ${id.toWat} ${compType.toWat})" end TypeInfo /** A WebAssembly exception tag declaration. @@ -241,22 +269,25 @@ end Ctx */ class Ctx( types: ArrayBuf[TypeInfo], - namedTypes: MutMap[BlockMemberSymbol, NumIdx], + namedTypes: MutMap[BlockMemberSymbol, Int], memoryImports: ArrayBuf[MemoryImport], functionImports: ArrayBuf[FuncImport], dataSegments: ArrayBuf[DataSegment], funcs: ArrayBuf[FuncInfo], - funcInfosByIndex: MutMap[NumIdx, FuncInfo], + funcInfosByIndex: MutMap[Int, FuncInfo], globals: ArrayBuf[GlobalInfo], - namedFuncs: MutMap[Symbol, NumIdx], + namedFuncs: MutMap[Symbol, Int], tags: ArrayBuf[TagInfo], - namedGlobals: MutMap[Symbol, NumIdx], - var locals: Ls[MutMap[Local, NumIdx]], + namedGlobals: MutMap[Symbol, Int], + var locals: Ls[MutMap[Local, Int]], private var startFunc: Opt[FuncIdx], ) extends ToWat: import Ctx.prettyString + /** Counter for generating object tags. */ + private var objectTagNum = 0 + private val wasmIntrinsicFuncs: MutMap[Str, FuncIdx] = MutMap.empty private val wasmIntrinsicTypes: MutMap[WasmIntrinsicType, TypeIdx] = MutMap.empty private val wasmIntrinsicTags: MutMap[Str, TagIdx] = MutMap.empty @@ -281,37 +312,54 @@ class Ctx( labelTargets.collectFirst: case (sym, target) if sym eq label => target + /** Returns a new number to be used as an object tag. */ + def getFreshObjectTag(): Int = + val tag = objectTagNum + objectTagNum += 1 + tag + /** Adds a type into this context. */ def addType(sym: Opt[BlockMemberSymbol], typeInfo: TypeInfo): TypeIdx = - val numIdx = NumIdx(types.size) + val numIdx = types.size types += typeInfo sym.foreach: namedTypes(_) = numIdx - TypeIdx(typeInfo.id.getOrElse(numIdx)) + TypeIdx(typeInfo.id) + + @deprecated("Use the overload without `resolveSymIdx` instead.") + def getType(typeref: TypeIdx | BlockMemberSymbol, resolveSymIdx: Bool): Opt[TypeIdx] = + if resolveSymIdx then + typeref match + case TypeIdx(SymIdx(nme)) => + namedTypes.find(_._1.nme == nme).map(t => TypeIdx(NumIdx(t._2))) + case typeidx: TypeIdx => S(typeidx) + case sym: BlockMemberSymbol => namedTypes.get(sym).map(idx => TypeIdx(NumIdx(idx))) + else getType(typeref) /** Returns the [[TypeIdx]] of the given `typeref`, optionally resolving the symbolic index into a numeric index. */ - def getType(typeref: TypeIdx | BlockMemberSymbol, resolveSymIdx: Bool = false): Opt[TypeIdx] = - typeref match - case TypeIdx(SymIdx(nme)) if resolveSymIdx => - namedTypes.find(_._1.nme == nme).map(t => TypeIdx(t._2)) - case typeidx: TypeIdx => S(typeidx) - case sym: BlockMemberSymbol if resolveSymIdx => namedTypes.get(sym).map(TypeIdx(_)) - case sym: BlockMemberSymbol => - getType(sym, resolveSymIdx = true).map: numIdx => - getTypeInfo(numIdx).flatMap(_.id).fold(numIdx)(TypeIdx(_)) + def getType(typeref: TypeIdx | BlockMemberSymbol): Opt[TypeIdx] = typeref match + case typeidx: TypeIdx => S(typeidx) + case sym: BlockMemberSymbol => getTypeInfo(typeref).map(ti => TypeIdx(ti.id)) - /** Same as [[getType]] but throws an exception when the `typeref` is not found. */ - def getType_!(typeref: TypeIdx | BlockMemberSymbol, resolveSymIdx: Bool = false): TypeIdx = + @deprecated("Use the overload without `resolveSymIdx` instead.") + def getType_!(typeref: TypeIdx | BlockMemberSymbol, resolveSymIdx: Bool): TypeIdx = getType(typeref, resolveSymIdx).getOrElse: lastWords(s"Missing type definition for ${typeref.prettyString}") + /** Same as [[getType]] but throws an exception when the `typeref` is not found. */ + def getType_!(typeref: TypeIdx | BlockMemberSymbol): TypeIdx = + getType(typeref).getOrElse: + lastWords(s"Missing type definition for ${typeref.prettyString}") + /** Returns the [[TypeInfo]] instance associated with the given `typeref`. */ + @nowarn("cat=deprecation") def getTypeInfo(typeref: TypeIdx | BlockMemberSymbol): Opt[TypeInfo] = typeref match case TypeIdx(NumIdx(idx)) => types.unapply(idx.toInt) case TypeIdx(SymIdx(nme)) => - namedTypes.find(_._1.nme == nme).flatMap(t => getTypeInfo(TypeIdx(t._2))) - case sym: BlockMemberSymbol => namedTypes.get(sym).flatMap(idx => getTypeInfo(TypeIdx(idx))) + // TODO(Derppening): Consider adding a `Map[SymIdx, TypeInfo]` for faster lookup + types.find(_.id.id == nme) + case sym: BlockMemberSymbol => namedTypes.get(sym).map(idx => types(idx)) /** Same as [[getTypeInfo]] but throws an exception when the `typeref` is not found. */ def getTypeInfo_!(typeref: TypeIdx | BlockMemberSymbol): TypeInfo = @@ -320,23 +368,23 @@ class Ctx( /** Adds a function into this context. */ def addFunc(sym: Opt[Symbol], funcInfo: FuncInfo): FuncIdx = - val numIdx = NumIdx(functionImports.size + funcs.size) + val numIdx = functionImports.size + funcs.size funcs += funcInfo funcInfosByIndex(numIdx) = funcInfo sym.foreach: namedFuncs(_) = numIdx - FuncIdx(funcInfo.id.getOrElse(numIdx)) + FuncIdx(funcInfo.id) /** Adds a function import into this context. * * Returns the function index in the global function index space. */ def addFunctionImport(sym: Opt[Symbol], funcImport: FuncImport): FuncIdx = - val numIdx = NumIdx(functionImports.size + funcs.size) + val numIdx = functionImports.size + funcs.size functionImports += funcImport sym.foreach: namedFuncs(_) = numIdx - FuncIdx(funcImport.id.getOrElse(numIdx)) + FuncIdx(funcImport.id) /** Returns the cached function import for (`module`, `name`), creating it with `createImport` if needed. */ @@ -359,13 +407,18 @@ class Ctx( memoryImports(idx) = existing.copy(minPages = newMin) case N => val idx = memoryImports.size - memoryImports += MemoryImport(module, name, minPages) + memoryImports += MemoryImport(module, name, SymIdx(name), minPages) cachedMemoryImport(key) = idx /** Returns the minimum page requirement of memory import (`module`, `name`) if present. */ + @deprecated("Use `getMemoryImport` instead to get the full `MemoryImport` information.") def getMemoryImportMinPages(module: Str, name: Str): Opt[Int] = memoryImports.find(m => m.module === module && m.name === name).map(_.minPages) + /** Returns the memory import information for the given (`module`, `name`) tuple if present. */ + def getMemoryImport(module: Str, name: Str): Opt[MemoryImport] = + memoryImports.find(m => m.module === module && m.name === name) + /** Adds a data segment into this context. */ def addDataSegment(seg: DataSegment): Unit = dataSegments += seg @@ -375,29 +428,43 @@ class Ctx( tags += tagInfo TagIdx(tagInfo.id) + @deprecated("Use the overload without `resolveSymIdx` instead.") + def getFunc(funcref: FuncIdx | Symbol, resolveSymIdx: Bool): Opt[FuncIdx] = + if resolveSymIdx then + funcref match + case FuncIdx(SymIdx(nme)) if resolveSymIdx => + namedFuncs.find(_._1.nme == nme).map(f => FuncIdx(NumIdx(f._2))) + case funcidx: FuncIdx => S(funcidx) + case sym: Symbol => namedFuncs.get(sym).map(idx => FuncIdx(NumIdx(idx))) + else getFunc(funcref) + /** Returns the [[FuncIdx]] of the given `funcref`, optionally resolving the symbolic index into a numeric index. */ - def getFunc(funcref: FuncIdx | Symbol, resolveSymIdx: Bool = false): Opt[FuncIdx] = funcref match - case FuncIdx(SymIdx(nme)) if resolveSymIdx => - namedFuncs.find(_._1.nme == nme).map(f => FuncIdx(f._2)) + def getFunc(funcref: FuncIdx | Symbol): Opt[FuncIdx] = funcref match case funcidx: FuncIdx => S(funcidx) - case sym: Symbol if resolveSymIdx => namedFuncs.get(sym).map(FuncIdx(_)) - case sym: Symbol => - getFunc(sym, resolveSymIdx = true).map: numIdx => - getFuncInfo(numIdx).flatMap(_.id).fold(numIdx)(FuncIdx(_)) + case sym: Symbol => getFuncInfo(funcref).map(fi => FuncIdx(fi.id)) - /** Same as [[getFunc]] but throws an exception when the `funcref` is not found. */ - def getFunc_!(funcref: FuncIdx | Symbol, resolveSymIdx: Bool = false): FuncIdx = + @deprecated("Use the overload without `resolveSymIdx` instead.") + def getFunc_!(funcref: FuncIdx | Symbol, resolveSymIdx: Bool): FuncIdx = getFunc(funcref, resolveSymIdx).getOrElse: lastWords(s"Missing function definition for ${funcref.prettyString}") + /** Same as [[getFunc]] but throws an exception when the `funcref` is not found. */ + def getFunc_!(funcref: FuncIdx | Symbol): FuncIdx = + getFunc(funcref).getOrElse: + lastWords(s"Missing function definition for ${funcref.prettyString}") + /** Returns the [[FuncInfo]] instance associated with the given `funcref`. */ + @nowarn("cat=deprecation") def getFuncInfo(funcref: FuncIdx | Symbol): Opt[FuncInfo] = funcref match - case FuncIdx(numIdx @ NumIdx(idx)) => - funcInfosByIndex.get(numIdx).orElse: + case FuncIdx(NumIdx(idx)) => + funcInfosByIndex.get(idx).orElse: val localIdx = idx.toInt - functionImports.size if localIdx < 0 then N else funcs.unapply(localIdx) - case funcref => getFunc(funcref, resolveSymIdx = true).flatMap(getFuncInfo(_)) + case FuncIdx(SymIdx(nme)) => + // TODO(Derppening): Consider adding a `Map[SymIdx, FuncInfo]` for faster lookup + funcs.find(_.id.id == nme) + case funcref: Symbol => namedFuncs.get(funcref).map(idx => funcs(idx)) /** Same as [[getFuncInfo]] but throws an exception when the `funcref` is not found. */ def getFuncInfo_!(funcref: FuncIdx | Symbol): FuncInfo = @@ -412,9 +479,9 @@ class Ctx( /** Adds a new local variable into the top-most variable scope. */ def addLocal(sym: Local): LocalIdx = - val numIdx = NumIdx(locals.head.size) + val numIdx = locals.head.size locals.head(sym) = numIdx - LocalIdx(numIdx) + LocalIdx(SymIdx(sym.nme)) /** Adds a [[Seq]] of local variables into the top-most variable scope. */ def addLocals(syms: Seq[Local]): Seq[LocalIdx] = @@ -425,7 +492,7 @@ class Ctx( /** Adds a new variable into the global variable scope. */ def addGlobal(sym: Symbol, globalInfo: GlobalInfo): GlobalIdx = - val numIdx = NumIdx(globals.size) + val numIdx = globals.size globals += globalInfo namedGlobals(sym) = numIdx GlobalIdx(globalInfo.id) @@ -472,8 +539,8 @@ class Ctx( /** Converts a [[Map]] of symbols and their respective numeric identifiers into a [[Seq]] of symbols sorted by its * numeric index. */ - private def wasmLocalsToSeq(scope: Map[Symbol, NumIdx]): Seq[Local] = - scope.toSeq.sortBy(_._2.index).map(_._1) + private def wasmLocalsToSeq(scope: Map[Symbol, Int]): Seq[Local] = + scope.toSeq.sortBy(_._2).map(_._1) /** Returns a tuple containing the variables in the current `global` and `local` scopes respectively. */ diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Wasm.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Wasm.scala index 155e881def..b9290f8145 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Wasm.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/Wasm.scala @@ -113,23 +113,23 @@ case class FunctionType(sigType: SignatureType) extends ToWat: doc"(func${sigType.toWat.surroundUnlessEmpty(doc" ")})" /** A type representing a struct field. */ -case class Field(ty: Type, mutable: Bool, id: Opt[Str]) extends ToWat: +case class Field(ty: Type, mutable: Bool, id: SymIdx) extends ToWat: def toWat: Document = - doc"(field ${id.fold(doc"")(id => doc"$$$id ")}${ + doc"(field ${id.toWat} ${ if mutable then doc"(mut ${ty.toWat})" else ty.toWat })" /** A type representing a structure type. */ case class StructType( - fields: Map[DefinitionSymbol[?], NumIdx -> Field], + fields: Seq[DefinitionSymbol[?] -> Field], parents: Seq[TypeIdx] = Seq.empty, isSubtype: Bool = false, ) extends ToWat: - def fieldSeq: Seq[Field] = fields.values.toSeq.sortBy(_._1.index).map(_._2) + lazy val fieldsBySym: Map[DefinitionSymbol[?], Field] = fields.toMap def toWat: Document = - doc"(struct${fieldSeq.map(_.toWat).mkDocument(doc" ").surroundUnlessEmpty(doc" ")})" + doc"(struct${fields.map(_._2.toWat).mkDocument(doc" ").surroundUnlessEmpty(doc" ")})" /** A type representing an array type. */ case class ArrayType(elemType: Type, mutable: Bool) extends ToWat: @@ -158,6 +158,9 @@ type HeapType = AbsHeapType | TypeIdx sealed abstract class Index extends ToWat /** A numeric index. */ +@deprecated( + "NumIdx is only used for internal bookkeeping and should not be used in WAT generation; Use SymIdx instead.", +) case class NumIdx(val index: Int) extends Index: def toWat: Document = doc"${index.toString}" @@ -188,16 +191,14 @@ case class FieldIdx(idx: Index) extends CtxIdx(idx) case class TagIdx(idx: Index) extends CtxIdx(idx) /** A memory import entry. */ -case class MemoryImport(module: Str, name: Str, minPages: Int) extends ToWat: +case class MemoryImport(module: Str, name: Str, id: SymIdx, minPages: Int) extends ToWat: def toWat: Document = - doc"""(import "$module" "$name" (memory $minPages))""" + doc"""(import "$module" "$name" (memory ${id.toWat} $minPages))""" /** A function import entry. */ -case class FuncImport(module: Str, name: Str, id: Opt[SymIdx], typeIdx: TypeIdx) extends ToWat: +case class FuncImport(module: Str, name: Str, id: SymIdx, typeIdx: TypeIdx) extends ToWat: def toWat: Document = - doc"""(import "$module" "$name" (func ${ - id.fold(doc"")(_.toWat) - } (type ${typeIdx.toWat})))""" + doc"""(import "$module" "$name" (func ${id.toWat} (type ${typeIdx.toWat})))""" /** A data segment entry. */ case class DataSegment(offsetExpr: Expr, bytes: Str) extends ToWat: diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/WatBuilder.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/WatBuilder.scala index 8465d5e6b3..1ee1ce4dc5 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/WatBuilder.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/wasm/text/WatBuilder.scala @@ -136,7 +136,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: ) val ctorCall = call( - funcidx = ctx.getFunc_!(clsLikeDefn.sym, resolveSymIdx = true), + funcidx = ctx.getFunc_!(clsLikeDefn.sym), operands = Seq.empty, returnTypes = Seq(Result(RefType.anyref)), ) @@ -144,26 +144,25 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: end registerSingletonInit /** Recursively declares supported top-level class types (needed for nested function codegen). */ - private def createDefnTypes(b: Block)(using Ctx): Unit = b match + private def createDefnTypes(b: Block)(using Ctx, Raise, Scope): Unit = b match case Define(defn: ClsLikeDefn, rst) => if isSupportedTopLevelClass(defn) then - val inheritedFields = baseObjectStruct.fields.toMap + val inheritedFields = baseObjectStruct.fields val inheritedSize = inheritedFields.size - val classFields: Map[DefinitionSymbol[?], NumIdx -> Field] = (defn.publicFields.map(_._2) ++ defn.privateFields) - .zipWithIndex - .map: (f, index) => - f -> (NumIdx(index + inheritedSize) -> Field(RefType.anyref, mutable = true, id = S(f.nme))) - .toMap + val classFields = (defn.publicFields.map(_._2) ++ defn.privateFields) + .map: f => + f -> Field(RefType.anyref, mutable = true, id = SymIdx(f.nme)) - val allFields: Map[DefinitionSymbol[?], NumIdx -> Field] = inheritedFields ++ classFields + val allFields = inheritedFields ++ classFields // Only parent is base Object for now. For general inheritance add other parents. ctx.addType( sym = S(defn.sym), typeInfo = TypeInfo( - id = S(SymIdx(defn.sym.nme)), + sym = defn.sym, compType = StructType(fields = allFields, parents = Seq(baseObjectTypeIdx), isSubtype = true), + objectTag = S(ctx.getFreshObjectTag()), ), ) end if @@ -194,7 +193,8 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: case _: BlockTail => () /** Gets (and caches) the exception tag used for MLX `throw`. */ - private def exnTagIdx(using Ctx): TagIdx = + private def exnTagIdx(using Ctx, Raise, Scope): TagIdx = + val symNme = scope.allocateName(TempSymbol(N, "mlx_exn")) ctx.getOrCreateWasmIntrinsicTag( "mlx_exn", ctx.addTag(TagInfo( @@ -202,8 +202,9 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: typeIdx = ctx.addType( sym = N, TypeInfo( - id = N, + id = SymIdx(symNme), FunctionType(params = Seq(WasmParam(N, RefType.anyref)), results = Seq.empty), + objectTag = S(ctx.getFreshObjectTag()), ), ), )), @@ -231,7 +232,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: /** Ensures imports required for string materialization exist and returns the constructor function. */ - private def getOrLoadStrCtorFunction(using Ctx): FuncIdx = + private def getOrLoadStrCtorFunction(using Ctx, Raise, Scope): FuncIdx = val minBytes = nextStringDataOffset val pageSize = ExternIntrinsics.WasmPageSizeBytes val minPages = @@ -246,27 +247,29 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: module = ExternIntrinsics.SystemModule, name = ExternIntrinsics.StringFromUtf16ImportName, ): + val importTyNme = scope.allocateName(TempSymbol(N, ExternIntrinsics.StringFromUtf16ImportName)) val importTy = ctx.addType( sym = N, TypeInfo( - id = N, + id = SymIdx(importTyNme), FunctionType( params = Seq(WasmParam(N, RefType.anyref), WasmParam(N, RefType.anyref)), results = Seq(Result(RefType.anyref)), ), + objectTag = N, ), ) FuncImport( module = ExternIntrinsics.SystemModule, name = ExternIntrinsics.StringFromUtf16ImportName, - id = S(SymIdx(ExternIntrinsics.StringFromUtf16ImportName)), + id = SymIdx(ExternIntrinsics.StringFromUtf16ImportName), typeIdx = importTy, ) end getOrLoadStrCtorFunction /** Gets (and caches) the Wasm GC array type used for tuples (`mut` selects mutability). */ - private def tupleArrayType(mut: Bool)(using Ctx): TypeIdx = + private def tupleArrayType(mut: Bool)(using Ctx, Raise, Scope): TypeIdx = ctx.getOrCreateWasmIntrinsicType(WasmIntrinsicType.TupleArray(mutable = mut)): val suffix = if mut then "Mut" else "" val sym = BlockMemberSymbol(s"TupleArray$suffix", Nil) @@ -275,6 +278,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: TypeInfo( sym, ArrayType(elemType = RefType.anyref, mutable = mut), + objectTag = N, ), ) @@ -495,7 +499,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: )(using Ctx, Raise): FieldIdx = val structInfo = ctx.getTypeInfo_!(thisSym) val symToField = structInfo.compType match - case ty: StructType => ty.fields + case ty: StructType => ty.fieldsBySym case _ => lastWords(s"Cannot select field from non-struct type: ${structInfo.compType.toWat}") val fieldIdx = symToField.get(sym) .orElse: @@ -504,7 +508,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: case trmSym: TermSymbol if trmSym.owner.flatMap(_.asBlkMember).exists(_ == thisSym) => symToField.find((fieldSym, _) => fieldSym.nme == sym.nme).map((_, v) => v) case _ => N - .map((fieldidx, _) => fieldidx) + .map(_.id) FieldIdx( fieldIdx getOrElse: lastWords( @@ -738,12 +742,12 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: /** Gets (or creates) the intrinsic function implementing the wasm operator `name`. */ - private def getIntrinsic(name: Str)(using Ctx, Scope): FuncIdx = + private def getIntrinsic(name: Str)(using Ctx, Raise, Scope): FuncIdx = ctx.getOrCreateWasmIntrinsic(name, createIntrinsic(name)) /** Creates the intrinsic definition for `name`. */ - private def createIntrinsic(name: Str)(using Ctx, Scope): FuncIdx = + private def createIntrinsic(name: Str)(using Ctx, Raise, Scope): FuncIdx = if binaryOps.contains(name) then createBinaryInt31Func(name, binaryOps(name)) else if unaryOps.contains(name) then createUnaryInt31Func(name, unaryOps(name)) else lastWords(s"Unsupported wasm intrinsic '$name'") @@ -753,7 +757,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: private def createBinaryInt31Func( name: Str, op: (Expr, Expr) => Expr, - )(using Ctx, Scope): FuncIdx = + )(using Ctx, Raise, Scope): FuncIdx = val params = mkIntrinsicParams(name, Seq("lhs", "rhs")) val lhsName = params.head._2 val rhsName = params(1)._2 @@ -762,7 +766,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: /** Creates a unary Int31 intrinsic with a single parameter and body built from `op`. */ - private def createUnaryInt31Func(name: Str, op: Expr => Expr)(using Ctx, Scope): FuncIdx = + private def createUnaryInt31Func(name: Str, op: Expr => Expr)(using Ctx, Raise, Scope): FuncIdx = val params = mkIntrinsicParams(name, Seq("arg")) val argName = params.head._2 val body = unaryInt31Body(argName, op) @@ -774,24 +778,26 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: name: Str, params: Seq[(TempSymbol, Str)], body: Expr, - )(using Ctx): FuncIdx = + )(using Ctx, Raise, Scope): FuncIdx = val funcTy = ctx.addType( sym = N, TypeInfo( - id = N, + id = SymIdx(scope.allocateName(TempSymbol(N, name))), FunctionType( params = params.map((_, nme) => WasmParam(S(nme), RefType.anyref)), results = Seq(Result(RefType.anyref)), ), + objectTag = N, ), ) val funcInfo = FuncInfo( - id = N, + id = SymIdx(scope.allocateName(TempSymbol(N, name))), typeIdx = funcTy, params = params, nResults = 1, locals = Seq.empty, body = body, + `export` = N, ) ctx.addFunc(N, funcInfo) end createIntrinsicFunc @@ -1016,11 +1022,12 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: val funcTy = ctx.addType( sym = N, TypeInfo( - id = N, + id = SymIdx(scope.allocateName(TempSymbol(N, sym.nme))), FunctionType( params = params.map(_._1), results = Seq.fill(bodyWat.resultTypes.length)(Result(RefType.anyref)), ), + objectTag = N, ), ) @@ -1080,6 +1087,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: // Use the symbolic type reference (e.g. `$Foo`) in emitted WAT for readability. // Numeric indices are only needed for `$tag` values. val typeref = ctx.getType_!(clsLikeDefn.sym) + val typeinfo = ctx.getTypeInfo_!(typeref) val (ctorParams, thisVar, ctorWat, ctorLocals) = setupCtorLocals(clsLikeDefn) @@ -1090,16 +1098,15 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: case Nil => (ctorAuxParams, Nil) case Some(_) => (ctorAuxParams, ctorParams) - val tagValue = ctx.getType_!(clsLikeDefn.sym, resolveSymIdx = true) match - case TypeIdx(NumIdx(idx)) => idx - case _ => lastWords(s"Expected numeric type index for class ${clsLikeDefn.sym}") + val tagValue = typeinfo.objectTag.getOrElse: + lastWords(s"Expected class ${clsLikeDefn.sym} to have an object tag") val ctorCode = blockInstr( label = N, Seq( local.set(thisVar, struct.new_default(typeref)), struct.set( - FieldIdx(NumIdx(0)), + FieldIdx(typeinfo.compType.asInstanceOf[StructType].fields(0)._2.id), ref.cast( local.get(thisVar, RefType.anyref), RefType(typeref, nullable = false), @@ -1117,32 +1124,41 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: else break(errUnimplExpr("newCtorAuxParams.nonEmpty")) - val funcTyId = - if isSingletonObj then S(SymIdx(s"${clsLikeDefn.sym.nme}_ctor")) - else N + val funcTyId = clsLikeDefn.sym + .optionIf: sym => + !isSingletonObj && sym.nameIsMeaningful + .map: sym => + s"${sym.nme}_ctor" + .getOrElse: + scope.allocateName(TempSymbol(N, s"${clsLikeDefn.sym.nme}_ctor")) val funcTy = ctx.addType( sym = N, TypeInfo( - id = funcTyId, + id = SymIdx(funcTyId), FunctionType( params = ctorParams.map(p => WasmParam(S(p._2), RefType.anyref)), results = Seq(Result(RefType.anyref)), ), + objectTag = N, ), ) - val ctorId = - if isSingletonObj then N - else clsLikeDefn.sym.optionIf(_.nameIsMeaningful).map(sym => SymIdx(sym.nme)) + val ctorId = clsLikeDefn.sym + .optionIf: sym => + !isSingletonObj && sym.nameIsMeaningful + .map: sym => + s"${sym.nme}_ctor" ctx.addFunc( S(clsLikeDefn.sym), FuncInfo( - id = ctorId, + id = + SymIdx(ctorId.getOrElse(scope.allocateName(TempSymbol(N, s"${clsLikeDefn.sym.nme}_ctor")))), typeIdx = funcTy, params = ctorParams, nResults = ctorCode.resultTypes.length, locals = ctorLocals, body = ctorAux, + `export` = ctorId, ), ) if isSingletonObj then @@ -1333,14 +1349,11 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: Ls(msg"Could not resolve BlockMemberSymbol for class pattern" -> cls.toLoc), extraInfo = S(s"ClassLikeSymbol: ${cls.toString}"), )) - val clsTypeIdx = ctx.getType_!(clsBlkMemberSym, resolveSymIdx = true) + val clsTypeIdx = ctx.getType_!(clsBlkMemberSym) + val typeinfo = ctx.getTypeInfo_!(clsTypeIdx) - val expectedTag = clsTypeIdx match - case TypeIdx(NumIdx(idx)) => idx - case _ => break(errExpr( - Ls(msg"Expected numeric type index for class pattern" -> cls.toLoc), - extraInfo = S(s"TypeIdx: ${clsTypeIdx}"), - )) + val expectedTag = typeinfo.objectTag.getOrElse: + lastWords(s"Expected class $clsBlkMemberSym to have an object tag") val scrutExpr = getScrutExpr val isStructCompatible = ref.test(scrutExpr, baseObjectRefType(nullable = true)) @@ -1352,7 +1365,11 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: // Safe to cast and extract tag since ref.test passed val scrutAsObject = ref.cast(scrutExpr, baseObjectRefType(nullable = false)) - val scrutTag = struct.get(FieldIdx(NumIdx(0)), scrutAsObject, I32Type) + val scrutTag = struct.get( + FieldIdx(typeinfo.compType.asInstanceOf[StructType].fields(0)._2.id), + scrutAsObject, + I32Type, + ) val tagMatches = i32.eq(scrutTag, i32.const(expectedTag)) S(`if`( @@ -1487,11 +1504,12 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: ctx.addType( sym = S(baseObjectSym), TypeInfo( - id = S(SymIdx("Object")), + id = SymIdx("Object"), StructType( - Map(tagFieldSym -> (NumIdx(0) -> Field(I32Type, mutable = true, id = S("$tag")))), + Seq(tagFieldSym -> Field(I32Type, mutable = true, id = SymIdx("$tag"))), isSubtype = true, ), + objectTag = S(ctx.getFreshObjectTag() ensuring (_ == 0)), ), ) @@ -1511,16 +1529,21 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: val entryFnTy = ctx.addType( sym = N, - TypeInfo(id = N, FunctionType(params = Seq.empty, results = Seq(Result(RefType.anyref)))), + TypeInfo( + id = SymIdx(scope.allocateName(TempSymbol(N, entryNme))), + FunctionType(params = Seq.empty, results = Seq(Result(RefType.anyref))), + objectTag = N, + ), ) val entryFnInfo = FuncInfo( - id = S(SymIdx(entryNme)), + id = SymIdx(entryNme), typeIdx = entryFnTy, params = Seq.empty, nResults = 1, // TODO(Derppening): Should we place top-level scope variables in the global section? locals = (entryFnLocals ++ entryExtraLocals).map(l => l -> scope.allocateOrGetName(l)), body = entryFnExpr, + `export` = S(entryNme), ) ctx.popLocal() @@ -1534,8 +1557,9 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: val initTy = ctx.addType( sym = N, TypeInfo( - id = S(SymIdx("start")), + id = SymIdx(scope.allocateName(TempSymbol(N, "start"))), FunctionType(params = Seq.empty, results = Seq.empty), + objectTag = N, ), ) val initBody = blockInstr( @@ -1546,12 +1570,13 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: val initFn = ctx.addFunc( sym = N, FuncInfo( - id = N, + id = SymIdx(scope.allocateName(TempSymbol(N, "start"))), typeIdx = initTy, params = Seq.empty, nResults = 0, locals = Seq.empty, body = initBody, + `export` = N, ), ) ctx.setStartFunc(initFn) @@ -1560,7 +1585,7 @@ class WatBuilder(using TraceLogger, State) extends CodeBuilder: ctx.addFunc(S(entrySym), entryFnInfo) val systemMemMinPages = - ctx.getMemoryImportMinPages(ExternIntrinsics.SystemModule, ExternIntrinsics.SystemMemoryImportName).getOrElse(0) + ctx.getMemoryImport(ExternIntrinsics.SystemModule, ExternIntrinsics.SystemMemoryImportName).fold(0)(_.minPages) (ctx.toWat, entryNme, systemMemMinPages) end program diff --git a/hkmc2/shared/src/test/mlscript/wasm/Basics.mls b/hkmc2/shared/src/test/mlscript/wasm/Basics.mls index 5d9f5691aa..080f8d0469 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Basics.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Basics.mls @@ -49,16 +49,16 @@ foo() + foo() //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (result (ref null any)))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $foo (type 1) (result (ref null any)) +//│ (type $foo1 (func (result (ref null any)))) +//│ (type $plus_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $foo (type $foo1) (result (ref null any)) //│ (return //│ (ref.i31 //│ (i32.const 42)))) //│ (export "foo" (func $foo)) //│ (elem declare func $foo) -//│ (func (type 2) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (func $plus_impl1 (type $plus_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -76,7 +76,8 @@ foo() + foo() //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func $entry (type 3) (result (ref null any)) +//│ (elem declare func $plus_impl1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $foo (ref null any)) //│ (local $tmp (ref null any)) //│ (local $tmp1 (ref null any)) @@ -84,13 +85,13 @@ foo() + foo() //│ (nop) //│ (block (result (ref null any)) //│ (local.set $tmp -//│ (call_ref 1 +//│ (call_ref $foo1 //│ (ref.func $foo))) //│ (block (result (ref null any)) //│ (local.set $tmp1 -//│ (call_ref 1 +//│ (call_ref $foo1 //│ (ref.func $foo))) -//│ (call 1 +//│ (call $plus_impl1 //│ (local.get $tmp) //│ (local.get $tmp1)))))) //│ (export "entry" (func $entry)) @@ -118,38 +119,38 @@ class Foo(val a) //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $Foo (sub $Object (struct (field $$tag (mut i32)) (field $a (mut (ref null any)))))) -//│ (type (func (param $a (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $Foo (type 2) (param $a (ref null any)) (result (ref null any)) +//│ (type $Foo_ctor (func (param $a (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $Foo_ctor (type $Foo_ctor) (param $a (ref null any)) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Foo)) -//│ (struct.set $Foo 0 +//│ (struct.set $Foo $$tag //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $Foo 1 +//│ (struct.set $Foo $a //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (local.get $a)) //│ (nop)) //│ (return //│ (local.get $this)))) -//│ (export "Foo" (func $Foo)) -//│ (elem declare func $Foo) -//│ (func $entry (type 3) (result (ref null any)) +//│ (export "Foo_ctor" (func $Foo_ctor)) +//│ (elem declare func $Foo_ctor) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $Foo (ref null any)) //│ (local $tmp (ref null any)) //│ (block (result (ref null any)) //│ (nop) //│ (block (result (ref null any)) //│ (local.set $tmp -//│ (call $Foo +//│ (call $Foo_ctor //│ (ref.i31 //│ (i32.const 42)))) -//│ (struct.get $Foo 1 +//│ (struct.get $Foo $a //│ (ref.cast (ref $Foo) //│ (local.get $tmp)))))) //│ (export "entry" (func $entry)) @@ -172,45 +173,45 @@ class Foo(val x) with //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $Foo (sub $Object (struct (field $$tag (mut i32)) (field $x (mut (ref null any))) (field $y (mut (ref null any)))))) -//│ (type (func (param $x (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $Foo (type 2) (param $x (ref null any)) (result (ref null any)) +//│ (type $Foo_ctor (func (param $x (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $Foo_ctor (type $Foo_ctor) (param $x (ref null any)) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Foo)) -//│ (struct.set $Foo 0 +//│ (struct.set $Foo $$tag //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $Foo 1 +//│ (struct.set $Foo $x //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (local.get $x)) //│ (block -//│ (struct.set $Foo 2 +//│ (struct.set $Foo $y //│ (ref.cast (ref $Foo) //│ (local.get $this)) -//│ (struct.get $Foo 1 +//│ (struct.get $Foo $x //│ (ref.cast (ref $Foo) //│ (local.get $this)))) //│ (nop))) //│ (return //│ (local.get $this)))) -//│ (export "Foo" (func $Foo)) -//│ (elem declare func $Foo) -//│ (func $entry (type 3) (result (ref null any)) +//│ (export "Foo_ctor" (func $Foo_ctor)) +//│ (elem declare func $Foo_ctor) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $Foo (ref null any)) //│ (local $tmp (ref null any)) //│ (block (result (ref null any)) //│ (nop) //│ (block (result (ref null any)) //│ (local.set $tmp -//│ (call $Foo +//│ (call $Foo_ctor //│ (ref.i31 //│ (i32.const 42)))) -//│ (struct.get $Foo 2 +//│ (struct.get $Foo $y //│ (ref.cast (ref $Foo) //│ (local.get $tmp)))))) //│ (export "entry" (func $entry)) @@ -229,45 +230,47 @@ O.y //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $O (sub $Object (struct (field $$tag (mut i32)) (field $x (mut (ref null any))) (field $y (mut (ref null any)))))) //│ (type $O_ctor (func (result (ref null any)))) -//│ (type (func (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) //│ (type $start (func)) //│ (global $O$inst (mut (ref null $O)) (ref.null $O)) -//│ (start 1) -//│ (func (type $O_ctor) (result (ref null any)) +//│ (start $start1) +//│ (func $O_ctor1 (type $O_ctor) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $O)) -//│ (struct.set $O 0 +//│ (struct.set $O $$tag //│ (ref.cast (ref $O) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $O 1 +//│ (struct.set $O $x //│ (ref.cast (ref $O) //│ (local.get $this)) //│ (ref.i31 //│ (i32.const 1))) //│ (block -//│ (struct.set $O 2 +//│ (struct.set $O $y //│ (ref.cast (ref $O) //│ (local.get $this)) -//│ (struct.get $O 1 +//│ (struct.get $O $x //│ (ref.cast (ref $O) //│ (local.get $this)))) //│ (nop))) //│ (return //│ (local.get $this)))) -//│ (func (type $start) +//│ (elem declare func $O_ctor1) +//│ (func $start1 (type $start) //│ (block //│ (global.set $O$inst //│ (ref.cast (ref null $O) -//│ (call 0))))) -//│ (func $entry (type 3) (result (ref null any)) +//│ (call $O_ctor1))))) +//│ (elem declare func $start1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $O (ref null any)) //│ (block (result (ref null any)) //│ (nop) -//│ (struct.get $O 2 +//│ (struct.get $O $y //│ (ref.cast (ref $O) //│ (global.get $O$inst))))) //│ (export "entry" (func $entry)) diff --git a/hkmc2/shared/src/test/mlscript/wasm/BuiltinOperators.mls b/hkmc2/shared/src/test/mlscript/wasm/BuiltinOperators.mls index 0f50f09946..cce0c48ed4 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/BuiltinOperators.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/BuiltinOperators.mls @@ -7,9 +7,9 @@ //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func (type 1) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (type $plus_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $plus_impl1 (type $plus_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -27,8 +27,9 @@ //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func $entry (type 2) (result (ref null any)) -//│ (call 0 +//│ (elem declare func $plus_impl1) +//│ (func $entry (type $entry1) (result (ref null any)) +//│ (call $plus_impl1 //│ (ref.i31 //│ (i32.const 1)) //│ (ref.i31 @@ -43,9 +44,9 @@ //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $arg (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func (type 1) (param $arg (ref null any)) (result (ref null any)) +//│ (type $neg_impl (func (param $arg (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $neg_impl1 (type $neg_impl) (param $arg (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (ref.test (ref null i31) //│ (local.get $arg)) @@ -58,8 +59,9 @@ //│ (local.get $arg)))))) //│ (else //│ (unreachable)))) -//│ (func $entry (type 2) (result (ref null any)) -//│ (call 0 +//│ (elem declare func $neg_impl1) +//│ (func $entry (type $entry1) (result (ref null any)) +//│ (call $neg_impl1 //│ (ref.i31 //│ (i32.const 2)))) //│ (export "entry" (func $entry)) @@ -92,9 +94,9 @@ not true //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func (type 1) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (type $eq_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $eq_impl1 (type $eq_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -112,8 +114,9 @@ not true //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func $entry (type 2) (result (ref null any)) -//│ (call 0 +//│ (elem declare func $eq_impl1) +//│ (func $entry (type $entry1) (result (ref null any)) +//│ (call $eq_impl1 //│ (ref.i31 //│ (i32.const 1)) //│ (ref.i31 diff --git a/hkmc2/shared/src/test/mlscript/wasm/ControlFlow.mls b/hkmc2/shared/src/test/mlscript/wasm/ControlFlow.mls index a2e2077136..049866facb 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/ControlFlow.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/ControlFlow.mls @@ -10,15 +10,15 @@ let i = 0 in //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $lt_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $plus_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) //│ (type $Unit (sub $Object (struct (field $$tag (mut i32))))) //│ (type $Unit_ctor (func (result (ref null any)))) -//│ (type (func (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) //│ (type $start (func)) //│ (global $Unit$inst (mut (ref null $Unit)) (ref.null $Unit)) -//│ (start 3) -//│ (func (type 1) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (start $start1) +//│ (func $lt_impl1 (type $lt_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -36,7 +36,8 @@ let i = 0 in //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func (type 2) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (elem declare func $lt_impl1) +//│ (func $plus_impl1 (type $plus_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -54,24 +55,27 @@ let i = 0 in //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func (type $Unit_ctor) (result (ref null any)) +//│ (elem declare func $plus_impl1) +//│ (func $Unit_ctor1 (type $Unit_ctor) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Unit)) -//│ (struct.set $Unit 0 +//│ (struct.set $Unit $$tag //│ (ref.cast (ref $Unit) //│ (local.get $this)) -//│ (i32.const 3)) +//│ (i32.const 1)) //│ (nop) //│ (return //│ (local.get $this)))) -//│ (func (type $start) +//│ (elem declare func $Unit_ctor1) +//│ (func $start1 (type $start) //│ (block //│ (global.set $Unit$inst //│ (ref.cast (ref null $Unit) -//│ (call 2))))) -//│ (func $entry (type 5) (result (ref null any)) +//│ (call $Unit_ctor1))))) +//│ (elem declare func $start1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $i (ref null any)) //│ (local $scrut (ref null any)) //│ (local $tmp (ref null any)) @@ -86,7 +90,7 @@ let i = 0 in //│ (drop //│ (block (result (ref null any)) //│ (local.set $scrut -//│ (call 0 +//│ (call $lt_impl1 //│ (local.get $i) //│ (ref.i31 //│ (i32.const 10)))) @@ -105,7 +109,7 @@ let i = 0 in //│ (block //│ (block //│ (local.set $tmp -//│ (call 1 +//│ (call $plus_impl1 //│ (local.get $i) //│ (ref.i31 //│ (i32.const 1)))) @@ -205,9 +209,9 @@ tailMatchAllValue(1) //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $x (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $tailMatchAllValue (type 1) (param $x (ref null any)) (result (ref null any)) +//│ (type $tailMatchAllValue1 (func (param $x (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $tailMatchAllValue (type $tailMatchAllValue1) (param $x (ref null any)) (result (ref null any)) //│ (local $matchRes (ref null any)) //│ (block (result (ref null any)) //│ (block $match @@ -243,11 +247,11 @@ tailMatchAllValue(1) //│ (local.get $matchRes))) //│ (export "tailMatchAllValue" (func $tailMatchAllValue)) //│ (elem declare func $tailMatchAllValue) -//│ (func $entry (type 2) (result (ref null any)) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $tailMatchAllValue (ref null any)) //│ (block (result (ref null any)) //│ (nop) -//│ (call_ref 1 +//│ (call_ref $tailMatchAllValue1 //│ (ref.i31 //│ (i32.const 1)) //│ (ref.func $tailMatchAllValue)))) diff --git a/hkmc2/shared/src/test/mlscript/wasm/Exceptions.mls b/hkmc2/shared/src/test/mlscript/wasm/Exceptions.mls index 6547e2fe10..6a5a62d1ff 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Exceptions.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Exceptions.mls @@ -9,11 +9,11 @@ throw 1 //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (tag $mlx_exn (type 1)) +//│ (type $mlx_exn (func (param (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (tag $mlx_exn (type $mlx_exn)) //│ (export "mlx_exn" (tag $mlx_exn)) -//│ (func $entry (type 2) (result (ref null any)) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (throw $mlx_exn //│ (ref.i31 //│ (i32.const 1)))) diff --git a/hkmc2/shared/src/test/mlscript/wasm/Matching.mls b/hkmc2/shared/src/test/mlscript/wasm/Matching.mls index 0b9d3acc9e..d784485989 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Matching.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Matching.mls @@ -46,48 +46,48 @@ if Bar(true) is //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $Bar (sub $Object (struct (field $$tag (mut i32)) (field $y (mut (ref null any)))))) //│ (type $Baz (sub $Object (struct (field $$tag (mut i32)) (field $z (mut (ref null any)))))) -//│ (type (func (param $y (ref null any)) (result (ref null any)))) -//│ (type (func (param $z (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $Bar (type 3) (param $y (ref null any)) (result (ref null any)) +//│ (type $Bar_ctor (func (param $y (ref null any)) (result (ref null any)))) +//│ (type $Baz_ctor (func (param $z (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $Bar_ctor (type $Bar_ctor) (param $y (ref null any)) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Bar)) -//│ (struct.set $Bar 0 +//│ (struct.set $Bar $$tag //│ (ref.cast (ref $Bar) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $Bar 1 +//│ (struct.set $Bar $y //│ (ref.cast (ref $Bar) //│ (local.get $this)) //│ (local.get $y)) //│ (nop)) //│ (return //│ (local.get $this)))) -//│ (export "Bar" (func $Bar)) -//│ (elem declare func $Bar) -//│ (func $Baz (type 4) (param $z (ref null any)) (result (ref null any)) +//│ (export "Bar_ctor" (func $Bar_ctor)) +//│ (elem declare func $Bar_ctor) +//│ (func $Baz_ctor (type $Baz_ctor) (param $z (ref null any)) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Baz)) -//│ (struct.set $Baz 0 +//│ (struct.set $Baz $$tag //│ (ref.cast (ref $Baz) //│ (local.get $this)) //│ (i32.const 2)) //│ (block -//│ (struct.set $Baz 1 +//│ (struct.set $Baz $z //│ (ref.cast (ref $Baz) //│ (local.get $this)) //│ (local.get $z)) //│ (nop)) //│ (return //│ (local.get $this)))) -//│ (export "Baz" (func $Baz)) -//│ (elem declare func $Baz) -//│ (func $entry (type 5) (result (ref null any)) +//│ (export "Baz_ctor" (func $Baz_ctor)) +//│ (elem declare func $Baz_ctor) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $Bar (ref null any)) //│ (local $Baz (ref null any)) //│ (local $scrut (ref null any)) @@ -103,10 +103,10 @@ if Bar(true) is //│ (nop) //│ (block (result (ref null any)) //│ (local.set $scrut -//│ (call_ref 3 +//│ (call_ref $Bar_ctor //│ (ref.i31 //│ (i32.const 1)) -//│ (ref.func $Bar))) +//│ (ref.func $Bar_ctor))) //│ (block (result (ref null any)) //│ (block $match //│ (local.set $matchRes @@ -117,7 +117,7 @@ if Bar(true) is //│ (then //│ (if //│ (i32.eq -//│ (struct.get $Object 0 +//│ (struct.get $Object $$tag //│ (ref.cast (ref $Object) //│ (local.get $scrut))) //│ (i32.const 1)) @@ -126,7 +126,7 @@ if Bar(true) is //│ (local.set $matchRes //│ (block (result (ref null any)) //│ (local.set $arg$Bar$0$ -//│ (struct.get $Bar 1 +//│ (struct.get $Bar $y //│ (ref.cast (ref $Bar) //│ (local.get $scrut)))) //│ (block (result (ref null any)) @@ -159,7 +159,7 @@ if Bar(true) is //│ (then //│ (if //│ (i32.eq -//│ (struct.get $Object 0 +//│ (struct.get $Object $$tag //│ (ref.cast (ref $Object) //│ (local.get $scrut))) //│ (i32.const 2)) @@ -168,7 +168,7 @@ if Bar(true) is //│ (local.set $matchRes //│ (block (result (ref null any)) //│ (local.set $arg$Baz$0$ -//│ (struct.get $Baz 1 +//│ (struct.get $Baz $z //│ (ref.cast (ref $Baz) //│ (local.get $scrut)))) //│ (block (result (ref null any)) diff --git a/hkmc2/shared/src/test/mlscript/wasm/ScopedLocals.mls b/hkmc2/shared/src/test/mlscript/wasm/ScopedLocals.mls index 775d0a2e3c..20f3f17a67 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/ScopedLocals.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/ScopedLocals.mls @@ -10,9 +10,9 @@ topA + topB //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func (type 1) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (type $plus_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $plus_impl1 (type $plus_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -30,7 +30,8 @@ topA + topB //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func $entry (type 2) (result (ref null any)) +//│ (elem declare func $plus_impl1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $topA (ref null any)) //│ (local $topB (ref null any)) //│ (block (result (ref null any)) @@ -41,7 +42,7 @@ topA + topB //│ (local.set $topB //│ (ref.i31 //│ (i32.const 2))) -//│ (call 0 +//│ (call $plus_impl1 //│ (local.get $topA) //│ (local.get $topB))))) //│ (export "entry" (func $entry)) @@ -59,10 +60,10 @@ chain(1) //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) -//│ (type (func (param $x (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func (type 1) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) +//│ (type $plus_impl (func (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)))) +//│ (type $chain1 (func (param $x (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $plus_impl1 (type $plus_impl) (param $lhs (ref null any)) (param $rhs (ref null any)) (result (ref null any)) //│ (if (result (ref null any)) //│ (i32.and //│ (ref.test (ref null i31) @@ -80,32 +81,33 @@ chain(1) //│ (local.get $rhs)))))) //│ (else //│ (unreachable)))) -//│ (func $chain (type 2) (param $x (ref null any)) (result (ref null any)) +//│ (elem declare func $plus_impl1) +//│ (func $chain (type $chain1) (param $x (ref null any)) (result (ref null any)) //│ (local $a (ref null any)) //│ (local $b (ref null any)) //│ (block (result (ref null any)) //│ (local.set $a -//│ (call 0 +//│ (call $plus_impl1 //│ (local.get $x) //│ (ref.i31 //│ (i32.const 1)))) //│ (block (result (ref null any)) //│ (local.set $b -//│ (call 0 +//│ (call $plus_impl1 //│ (local.get $a) //│ (ref.i31 //│ (i32.const 1)))) //│ (return -//│ (call 0 +//│ (call $plus_impl1 //│ (local.get $a) //│ (local.get $b)))))) //│ (export "chain" (func $chain)) //│ (elem declare func $chain) -//│ (func $entry (type 3) (result (ref null any)) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $chain (ref null any)) //│ (block (result (ref null any)) //│ (nop) -//│ (call_ref 2 +//│ (call_ref $chain1 //│ (ref.i31 //│ (i32.const 1)) //│ (ref.func $chain)))) @@ -169,45 +171,45 @@ class Foo(val a, val b) //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $Foo (sub $Object (struct (field $$tag (mut i32)) (field $a (mut (ref null any))) (field $b (mut (ref null any)))))) -//│ (type (func (param $a (ref null any)) (param $b (ref null any)) (result (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $Foo (type 2) (param $a (ref null any)) (param $b (ref null any)) (result (ref null any)) +//│ (type $Foo_ctor (func (param $a (ref null any)) (param $b (ref null any)) (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $Foo_ctor (type $Foo_ctor) (param $a (ref null any)) (param $b (ref null any)) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Foo)) -//│ (struct.set $Foo 0 +//│ (struct.set $Foo $$tag //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $Foo 1 +//│ (struct.set $Foo $a //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (local.get $a)) //│ (block -//│ (struct.set $Foo 2 +//│ (struct.set $Foo $b //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (local.get $b)) //│ (nop))) //│ (return //│ (local.get $this)))) -//│ (export "Foo" (func $Foo)) -//│ (elem declare func $Foo) -//│ (func $entry (type 3) (result (ref null any)) +//│ (export "Foo_ctor" (func $Foo_ctor)) +//│ (elem declare func $Foo_ctor) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $Foo (ref null any)) //│ (local $tmp (ref null any)) //│ (block (result (ref null any)) //│ (nop) //│ (block (result (ref null any)) //│ (local.set $tmp -//│ (call $Foo +//│ (call $Foo_ctor //│ (ref.i31 //│ (i32.const 42)) //│ (ref.i31 //│ (i32.const 1)))) -//│ (struct.get $Foo 1 +//│ (struct.get $Foo $a //│ (ref.cast (ref $Foo) //│ (local.get $tmp)))))) //│ (export "entry" (func $entry)) diff --git a/hkmc2/shared/src/test/mlscript/wasm/SingletonUnit.mls b/hkmc2/shared/src/test/mlscript/wasm/SingletonUnit.mls index 7538ec47ea..df849c91bb 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/SingletonUnit.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/SingletonUnit.mls @@ -9,28 +9,30 @@ //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $Unit (sub $Object (struct (field $$tag (mut i32))))) //│ (type $Unit_ctor (func (result (ref null any)))) -//│ (type (func (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) //│ (type $start (func)) //│ (global $Unit$inst (mut (ref null $Unit)) (ref.null $Unit)) -//│ (start 1) -//│ (func (type $Unit_ctor) (result (ref null any)) +//│ (start $start1) +//│ (func $Unit_ctor1 (type $Unit_ctor) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Unit)) -//│ (struct.set $Unit 0 +//│ (struct.set $Unit $$tag //│ (ref.cast (ref $Unit) //│ (local.get $this)) //│ (i32.const 1)) //│ (nop) //│ (return //│ (local.get $this)))) -//│ (func (type $start) +//│ (elem declare func $Unit_ctor1) +//│ (func $start1 (type $start) //│ (block //│ (global.set $Unit$inst //│ (ref.cast (ref null $Unit) -//│ (call 0))))) -//│ (func $entry (type 3) (result (ref null any)) +//│ (call $Unit_ctor1))))) +//│ (elem declare func $start1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (global.get $Unit$inst)) //│ (export "entry" (func $entry)) //│ (elem declare func $entry)) @@ -74,8 +76,8 @@ x //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (result (ref null any)))) -//│ (func $entry (type 1) (result (ref null any)) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $x (ref null any)) //│ (block (result (ref null any)) //│ (local.set $x diff --git a/hkmc2/shared/src/test/mlscript/wasm/Singletons.mls b/hkmc2/shared/src/test/mlscript/wasm/Singletons.mls index dc31b18afb..a072393320 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Singletons.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Singletons.mls @@ -16,22 +16,22 @@ Bar.y //│ (type $Bar (sub $Object (struct (field $$tag (mut i32)) (field $y (mut (ref null any)))))) //│ (type $Foo_ctor (func (result (ref null any)))) //│ (type $Bar_ctor (func (result (ref null any)))) -//│ (type (func (result (ref null any)))) +//│ (type $entry1 (func (result (ref null any)))) //│ (type $start (func)) //│ (global $Foo$inst (mut (ref null $Foo)) (ref.null $Foo)) //│ (global $Bar$inst (mut (ref null $Bar)) (ref.null $Bar)) -//│ (start 2) -//│ (func (type $Foo_ctor) (result (ref null any)) +//│ (start $start1) +//│ (func $Foo_ctor1 (type $Foo_ctor) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Foo)) -//│ (struct.set $Foo 0 +//│ (struct.set $Foo $$tag //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (i32.const 1)) //│ (block -//│ (struct.set $Foo 1 +//│ (struct.set $Foo $x //│ (ref.cast (ref $Foo) //│ (local.get $this)) //│ (ref.i31 @@ -39,17 +39,18 @@ Bar.y //│ (nop)) //│ (return //│ (local.get $this)))) -//│ (func (type $Bar_ctor) (result (ref null any)) +//│ (elem declare func $Foo_ctor1) +//│ (func $Bar_ctor1 (type $Bar_ctor) (result (ref null any)) //│ (local $this (ref null any)) //│ (block (result (ref null any)) //│ (local.set $this //│ (struct.new_default $Bar)) -//│ (struct.set $Bar 0 +//│ (struct.set $Bar $$tag //│ (ref.cast (ref $Bar) //│ (local.get $this)) //│ (i32.const 2)) //│ (block -//│ (struct.set $Bar 1 +//│ (struct.set $Bar $y //│ (ref.cast (ref $Bar) //│ (local.get $this)) //│ (ref.i31 @@ -57,22 +58,24 @@ Bar.y //│ (nop)) //│ (return //│ (local.get $this)))) -//│ (func (type $start) +//│ (elem declare func $Bar_ctor1) +//│ (func $start1 (type $start) //│ (block //│ (global.set $Foo$inst //│ (ref.cast (ref null $Foo) -//│ (call 0))) +//│ (call $Foo_ctor1))) //│ (global.set $Bar$inst //│ (ref.cast (ref null $Bar) -//│ (call 1))))) -//│ (func $entry (type 5) (result (ref null any)) +//│ (call $Bar_ctor1))))) +//│ (elem declare func $start1) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $Bar (ref null any)) //│ (local $Foo (ref null any)) //│ (block (result (ref null any)) //│ (nop) //│ (block (result (ref null any)) //│ (nop) -//│ (struct.get $Bar 1 +//│ (struct.get $Bar $y //│ (ref.cast (ref $Bar) //│ (global.get $Bar$inst)))))) //│ (export "entry" (func $entry)) diff --git a/hkmc2/shared/src/test/mlscript/wasm/Strings.mls b/hkmc2/shared/src/test/mlscript/wasm/Strings.mls index 03ad153054..768c650564 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Strings.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Strings.mls @@ -17,14 +17,14 @@ let dup2 = "dup" //│ Wat: //│ (module //│ (type $Object (sub (struct (field $$tag (mut i32))))) -//│ (type (func (param (ref null any)) (param (ref null any)) (result (ref null any)))) +//│ (type $mlx_str_from_utf16 (func (param (ref null any)) (param (ref null any)) (result (ref null any)))) //│ (type $TupleArray (array (ref null any))) //│ (type $TupleArrayMut (array (mut (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (import "system" "mem" (memory 1)) -//│ (import "system" "mlx_str_from_utf16" (func $mlx_str_from_utf16 (type 1))) +//│ (type $entry1 (func (result (ref null any)))) +//│ (import "system" "mem" (memory $mem 1)) +//│ (import "system" "mlx_str_from_utf16" (func $mlx_str_from_utf16 (type $mlx_str_from_utf16))) //│ (data (i32.const 0) "\64\00\75\00\70\00") -//│ (func $entry (type 4) (result (ref null any)) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $dup1 (ref null any)) //│ (local $dup2 (ref null any)) //│ (local $tmp (ref null any)) diff --git a/hkmc2/shared/src/test/mlscript/wasm/Tuples.mls b/hkmc2/shared/src/test/mlscript/wasm/Tuples.mls index 0636d511d2..46025df1cf 100644 --- a/hkmc2/shared/src/test/mlscript/wasm/Tuples.mls +++ b/hkmc2/shared/src/test/mlscript/wasm/Tuples.mls @@ -54,8 +54,8 @@ c.[3] //│ (type $Object (sub (struct (field $$tag (mut i32))))) //│ (type $TupleArray (array (ref null any))) //│ (type $TupleArrayMut (array (mut (ref null any)))) -//│ (type (func (result (ref null any)))) -//│ (func $entry (type 3) (result (ref null any)) +//│ (type $entry1 (func (result (ref null any)))) +//│ (func $entry (type $entry1) (result (ref null any)) //│ (local $c (ref null any)) //│ (local $tuple (ref null any)) //│ (block (result (ref null any))