@@ -230,7 +230,13 @@ class WasmBuilder {
230230 .getOrElse(throw new Error (s " Module class should have a constructor, ${clazz.name}" ))
231231 val typeName = WasmTypeName .WasmStructTypeName (clazz.name.name)
232232 val globalInstanceName = WasmGlobalName .WasmModuleInstanceName .fromIR(clazz.name.name)
233- val ctorName = WasmFunctionName (clazz.name.name, ctor.name.name)
233+
234+ val ctorName = WasmFunctionName (
235+ ctor.flags.namespace,
236+ clazz.name.name,
237+ ctor.name.name
238+ )
239+
234240 val body = List (
235241 // global.get $module_name
236242 // ref.if_null
@@ -355,7 +361,7 @@ class WasmBuilder {
355361 Names .WasmTypeName .WasmITableTypeName (className),
356362 classInfo.methods.map { m =>
357363 WasmStructField (
358- Names .WasmFieldName (m.name.methodName ),
364+ Names .WasmFieldName (m.name.simpleName ),
359365 WasmRefNullType (WasmHeapType .Func (m.toWasmFunctionType().name)),
360366 isMutable = false
361367 )
@@ -397,97 +403,58 @@ class WasmBuilder {
397403 exportDef : IRTrees .TopLevelMethodExportDef
398404 )(implicit ctx : WasmContext ): Unit = {
399405 val method = exportDef.methodDef
400- val methodName = method.name match {
401- case lit : IRTrees .StringLiteral => lit
402- case _ => ???
403- }
404-
405- // hack
406- // export top[moduleID="main"] static def "foo"(arg: any): any = {
407- // val prep0: int = arg.asInstanceOf[int];
408- // mod:sample.Main$.foo;I;I(prep0)
409- // }
410- // ->
411- // export top[moduleID="main"] static def "foo"(arg: int): int = {
412- // val prep0: int = arg;
413- // mod:sample.Main$.foo;I;I(arg)
414- // }
415- val paramTypeMap = mutable.Map [IRTrees .LocalIdent , IRTypes .Type ]()
416- val nameMap = mutable.Map [IRTrees .LocalIdent , IRTrees .LocalIdent ]()
417- val resultType : IRTypes .Type = method.body.tpe
418- def collectMapping (t : IRTrees .Tree ): Unit = {
419- t match {
420- case IRTrees .Block (stats) => stats.foreach(collectMapping)
421- case IRTrees .VarDef (lhs, _, _, _, IRTrees .AsInstanceOf (IRTrees .VarRef (ident), tpe)) =>
422- paramTypeMap.update(ident, tpe) // arg -> int
423- nameMap.update(lhs, ident) // prep0 -> arg
424- case _ =>
425- }
426- }
427- def mutateTree (t : IRTrees .Tree ): IRTrees .Tree = {
428- t match {
429- case b : IRTrees .Block => IRTrees .Block (b.stats.map(mutateTree))(b.pos)
430- case vdef @ IRTrees .VarDef (_, _, _, _, IRTrees .AsInstanceOf (vref, tpe)) =>
431- vdef.copy(rhs = vref)(vdef.pos)
432- case app : IRTrees .Apply =>
433- app.copy(args = app.args.map(a => mutateTree(a)))(app.tpe)(app.pos)
434- case vref : IRTrees .VarRef =>
435- val newName = nameMap.getOrElse(vref.ident, throw new Error (" Invalid name" ))
436- vref.copy(ident = newName)(vref.tpe)(vref.pos)
437- case t => t
438- }
439- }
406+ val exportedName = exportDef.topLevelExportName
440407
441- collectMapping(method.body)
442- val newBody = mutateTree(method.body)
443- val newParams = method.args.map { arg =>
444- paramTypeMap.get(arg.name) match {
445- case None => arg
446- case Some (newTpe) => arg.copy(ptpe = newTpe)(arg.pos)
447- }
408+ if (method.restParam.isDefined) {
409+ throw new UnsupportedOperationException (
410+ s " Top-level export with ...rest param is unsupported at ${method.pos}: $method"
411+ )
448412 }
449413
450414 implicit val fctx = WasmFunctionContext (
451415 enclosingClassName = None ,
452- Names .WasmFunctionName (methodName ),
416+ Names .WasmFunctionName .forExport(exportedName ),
453417 receiverTyp = None ,
454- newParams ,
455- resultType
418+ method.args ,
419+ IRTypes . AnyType
456420 )
457421
458- WasmExpressionBuilder .generateIRBody(newBody, resultType )
422+ WasmExpressionBuilder .generateIRBody(method.body, IRTypes . AnyType )
459423
460424 val func = fctx.buildAndAddToContext()
461425
462- val exprt = new WasmExport .Function (
463- methodName.value,
464- func
465- )
426+ val exprt = new WasmExport .Function (exportedName, func)
466427 ctx.addExport(exprt)
467428 }
468429
469430 private def genFunction (
470431 clazz : LinkedClass ,
471432 method : IRTrees .MethodDef
472433 )(implicit ctx : WasmContext ): WasmFunction = {
473- val functionName = Names .WasmFunctionName (clazz.name.name, method.name.name)
434+ val functionName = Names .WasmFunctionName (
435+ method.flags.namespace,
436+ clazz.name.name,
437+ method.name.name
438+ )
474439
475440 // Receiver type for non-constructor methods needs to be `(ref any)` because params are invariant
476441 // Otherwise, vtable can't be a subtype of the supertype's subtype
477442 // Constructor can use the exact type because it won't be registered to vtables.
478443 val receiverTyp =
479- if (clazz.kind == ClassKind .HijackedClass )
480- transformType(IRTypes .BoxedClassToPrimType (clazz.name.name))
444+ if (method.flags.namespace.isStatic)
445+ None
446+ else if (clazz.kind == ClassKind .HijackedClass )
447+ Some (transformType(IRTypes .BoxedClassToPrimType (clazz.name.name)))
481448 else if (method.flags.namespace.isConstructor)
482- WasmRefNullType (WasmHeapType .Type (WasmTypeName .WasmStructTypeName (clazz.name.name)))
449+ Some ( WasmRefNullType (WasmHeapType .Type (WasmTypeName .WasmStructTypeName (clazz.name.name) )))
483450 else
484- WasmRefType .any
451+ Some ( WasmRefType .any)
485452
486453 // Prepare for function context, set receiver and parameters
487454 implicit val fctx = WasmFunctionContext (
488455 Some (clazz.className),
489456 functionName,
490- Some ( receiverTyp) ,
457+ receiverTyp,
491458 method.args,
492459 method.resultType
493460 )
0 commit comments