diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala index be9fc9a993..0701d2fd84 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/ClassEmitter.scala @@ -62,14 +62,14 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val parentVarWithGlobals = for (parentIdent <- superClass) yield { implicit val pos = parentIdent.pos if (shouldExtendJSError(className, superClass)) untrackedGlobalRef("Error") - else WithGlobals(globalVar("c", parentIdent.name)) + else WithGlobals(globalVar(VarField.c, parentIdent.name)) } WithGlobals.option(parentVarWithGlobals).flatMap { parentVar => - globalClassDef("c", className, parentVar, allES6Defs) + globalClassDef(VarField.c, className, parentVar, allES6Defs) } } else { - allES5Defs(globalVar("c", className)) + allES5Defs(globalVar(VarField.c, className)) } } else { // Wrap the entire class def in an accessor function @@ -77,11 +77,11 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val genStoreJSSuperClass = jsSuperClass.map { jsSuperClass => for (rhs <- desugarExpr(jsSuperClass, resultType = AnyType)) yield { - js.VarDef(fileLevelVar("superClass").ident, Some(rhs)) + js.VarDef(fileLevelVar(VarField.superClass).ident, Some(rhs)) } } - val classValueIdent = fileLevelVarIdent("b", genName(className)) + val classValueIdent = fileLevelVarIdent(VarField.b, genName(className)) val classValueVar = js.VarRef(classValueIdent) val createClassValueVar = genEmptyMutableLet(classValueIdent) @@ -115,14 +115,14 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { }), js.Return(classValueVar) ) - createAccessor <- globalFunctionDef("a", className, Nil, None, body) + createAccessor <- globalFunctionDef(VarField.a, className, Nil, None, body) } yield { createClassValueVar :: createAccessor } } { jsClassCaptures => val captureParamDefs = for (param <- jsClassCaptures) yield { implicit val pos = param.pos - val ident = fileLevelVarIdent("cc", genName(param.name.name), + val ident = fileLevelVarIdent(VarField.cc, genName(param.name.name), param.originalName.orElse(param.name.name)) js.ParamDef(ident) } @@ -138,7 +138,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { Nil ) - globalFunctionDef("a", className, captureParamDefs, None, body) + globalFunctionDef(VarField.a, className, captureParamDefs, None, body) } } } @@ -191,7 +191,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { } else { import TreeDSL._ - val ctorVar = globalVar("c", className) + val ctorVar = globalVar(VarField.c, className) val chainProtoWithGlobals = superClass match { case None => @@ -201,15 +201,15 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { untrackedGlobalRef("Error").map(chainPrototypeWithLocalCtor(className, ctorVar, _)) case Some(parentIdent) => - WithGlobals(List(ctorVar.prototype := js.New(globalVar("h", parentIdent.name), Nil))) + WithGlobals(List(ctorVar.prototype := js.New(globalVar(VarField.h, parentIdent.name), Nil))) } for { ctorFun <- jsConstructorFunWithGlobals realCtorDef <- - globalFunctionDef("c", className, ctorFun.args, ctorFun.restParam, ctorFun.body) + globalFunctionDef(VarField.c, className, ctorFun.args, ctorFun.restParam, ctorFun.body) inheritableCtorDef <- - globalFunctionDef("h", className, Nil, None, js.Skip()) + globalFunctionDef(VarField.h, className, Nil, None, js.Skip()) chainProto <- chainProtoWithGlobals } yield { ( @@ -222,7 +222,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { // Inheritable constructor js.DocComment("@constructor") :: inheritableCtorDef ::: - (globalVar("h", className).prototype := ctorVar.prototype) :: Nil + (globalVar(VarField.h, className).prototype := ctorVar.prototype) :: Nil ) } } @@ -249,7 +249,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { } yield { import TreeDSL._ - val ctorVar = fileLevelVar("b", genName(className)) + val ctorVar = fileLevelVar(VarField.b, genName(className)) js.DocComment("@constructor") :: (ctorVar := ctorFun) :: @@ -263,7 +263,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[js.Tree] = { if (jsSuperClass.isDefined) { - WithGlobals(fileLevelVar("superClass")) + WithGlobals(fileLevelVar(VarField.superClass)) } else { genJSClassConstructor(superClass.get.name, keepOnlyDangerousVarNames = true) } @@ -341,7 +341,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { superCtor: js.Tree)(implicit pos: Position): List[js.Tree] = { import TreeDSL._ - val dummyCtor = fileLevelVar("hh", genName(className)) + val dummyCtor = fileLevelVar(VarField.hh, genName(className)) List( js.DocComment("@constructor"), @@ -381,9 +381,9 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val value = genZeroOf(ftpe) if (flags.isMutable) - globallyMutableVarDef("t", "u", varScope, value, origName.orElse(name)) + globallyMutableVarDef(VarField.t, VarField.u, varScope, value, origName.orElse(name)) else - globalVarDef("t", varScope, value, origName.orElse(name)) + globalVarDef(VarField.t, varScope, value, origName.orElse(name)) } WithGlobals.flatten(defs) @@ -410,7 +410,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { } symbolValueWithGlobals.flatMap { symbolValue => - globalVarDef("r", (className, name), symbolValue, origName.orElse(name)) + globalVarDef(VarField.r, (className, name), symbolValue, origName.orElse(name)) } } @@ -426,7 +426,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { if field.flags.namespace.isStatic } yield { implicit val pos = field.pos - val classVarRef = fileLevelVar("b", genName(className)) + val classVarRef = fileLevelVar(VarField.b, genName(className)) val zero = genBoxedZeroOf(field.ftpe) field match { case FieldDef(_, name, originalName, _) => @@ -452,7 +452,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { def genStaticInitialization(className: ClassName)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): List[js.Tree] = { - val field = globalVar("sct", (className, StaticInitializerName), + val field = globalVar(VarField.sct, (className, StaticInitializerName), StaticInitializerOriginalName) js.Apply(field, Nil) :: Nil } @@ -462,7 +462,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): List[js.Tree] = { if (hasClassInitializer) { - val field = globalVar("sct", (className, ClassInitializerName), + val field = globalVar(VarField.sct, (className, ClassInitializerName), ClassInitializerOriginalName) js.Apply(field, Nil) :: Nil } else { @@ -518,12 +518,12 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { } val field = namespace match { - case MemberNamespace.Public => "f" - case MemberNamespace.Private => "p" - case MemberNamespace.PublicStatic => "s" - case MemberNamespace.PrivateStatic => "ps" - case MemberNamespace.Constructor => "ct" - case MemberNamespace.StaticConstructor => "sct" + case MemberNamespace.Public => VarField.f + case MemberNamespace.Private => VarField.p + case MemberNamespace.PublicStatic => VarField.s + case MemberNamespace.PrivateStatic => VarField.ps + case MemberNamespace.Constructor => VarField.ct + case MemberNamespace.StaticConstructor => VarField.sct } val methodName = method.name.name @@ -633,8 +633,8 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { import TreeDSL._ val classVarRef = - if (kind.isJSClass) fileLevelVar("b", genName(className)) - else globalVar("c", className) + if (kind.isJSClass) fileLevelVar(VarField.b, genName(className)) + else globalVar(VarField.c, className) if (namespace.isStatic) classVarRef else classVarRef.prototype @@ -740,7 +740,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { } val createIsStatWithGlobals = if (needIsFunction) { - globalFunctionDef("is", className, List(objParam), None, js.Return(isExpression)) + globalFunctionDef(VarField.is, className, List(objParam), None, js.Return(isExpression)) } else { WithGlobals.nil } @@ -748,15 +748,15 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val createAsStatWithGlobals = if (semantics.asInstanceOfs == Unchecked) { WithGlobals.nil } else { - globalFunctionDef("as", className, List(objParam), None, js.Return { + globalFunctionDef(VarField.as, className, List(objParam), None, js.Return { val isCond = - if (needIsFunction) js.Apply(globalVar("is", className), List(obj)) + if (needIsFunction) js.Apply(globalVar(VarField.is, className), List(obj)) else isExpression js.If(isCond || (obj === js.Null()), { obj }, { - genCallHelper("throwClassCastException", + genCallHelper(VarField.throwClassCastException, obj, js.StringLiteral(displayName)) }) }) @@ -791,7 +791,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val depth = depthParam.ref val createIsArrayOfStatWithGlobals = { - globalFunctionDef("isArrayOf", className, List(objParam, depthParam), None, { + globalFunctionDef(VarField.isArrayOf, className, List(objParam, depthParam), None, { js.Return(!(!({ genIsScalaJSObject(obj) && ((obj DOT "$classData" DOT "arrayDepth") === depth) && @@ -804,13 +804,13 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val createAsArrayOfStatWithGlobals = if (semantics.asInstanceOfs == Unchecked) { WithGlobals.nil } else { - globalFunctionDef("asArrayOf", className, List(objParam, depthParam), None, { + globalFunctionDef(VarField.asArrayOf, className, List(objParam, depthParam), None, { js.Return { - js.If(js.Apply(globalVar("isArrayOf", className), List(obj, depth)) || + js.If(js.Apply(globalVar(VarField.isArrayOf, className), List(obj, depth)) || (obj === js.Null()), { obj }, { - genCallHelper("throwArrayCastException", + genCallHelper(VarField.throwArrayCastException, obj, js.StringLiteral("L"+displayName+";"), depth) }) } @@ -858,7 +858,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { if (isObjectClass) js.Null() else js.Undefined() } { parent => - globalVar("d", parent.name) + globalVar(VarField.d, parent.name) } } else { js.Undefined() @@ -872,7 +872,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { /* Ancestors of hijacked classes, including java.lang.Object, have a * normal $is_pack_Class test but with a non-standard behavior. */ - WithGlobals(globalVar("is", className)) + WithGlobals(globalVar(VarField.is, className)) } else if (HijackedClasses.contains(className)) { /* Hijacked classes have a special isInstanceOf test. */ val xParam = js.ParamDef(js.Ident("x")) @@ -888,7 +888,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { * cannot be performed and must throw. */ if (kind != ClassKind.JSClass && kind != ClassKind.NativeJSClass) { - WithGlobals(globalVar("noIsInstance", CoreVar)) + WithGlobals(globalVar(VarField.noIsInstance, CoreVar)) } else if (kind == ClassKind.JSClass && !globalKnowledge.hasInstances(className)) { /* We need to constant-fold the instance test, to avoid emitting * `x instanceof $a_TheClass()`, because `$a_TheClass` won't be @@ -928,10 +928,10 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { val prunedParams = allParams.reverse.dropWhile(_.isInstanceOf[js.Undefined]).reverse - val typeData = js.Apply(js.New(globalVar("TypeData", CoreVar), Nil) DOT "initClass", + val typeData = js.Apply(js.New(globalVar(VarField.TypeData, CoreVar), Nil) DOT "initClass", prunedParams) - globalVarDef("d", className, typeData) + globalVarDef(VarField.d, className, typeData) } } @@ -940,7 +940,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { globalKnowledge: GlobalKnowledge, pos: Position): js.Tree = { import TreeDSL._ - globalVar("c", className).prototype DOT "$classData" := globalVar("d", className) + globalVar(VarField.c, className).prototype DOT "$classData" := globalVar(VarField.d, className) } def genModuleAccessor(className: ClassName, kind: ClassKind)( @@ -953,7 +953,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { require(kind.hasModuleAccessor, s"genModuleAccessor called with non-module class: $className") - val moduleInstance = fileLevelVarIdent("n", genName(className)) + val moduleInstance = fileLevelVarIdent(VarField.n, genName(className)) val createModuleInstanceField = genEmptyMutableLet(moduleInstance) @@ -967,7 +967,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { genNonNativeJSClassConstructor(className), Nil) } else { - js.New(globalVar("c", className), Nil) + js.New(globalVar(VarField.c, className), Nil) } } } @@ -990,13 +990,13 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { ) }, js.If(moduleInstanceVar === js.Null(), { val decodedName = className.nameString.stripSuffix("$") - genCallHelper("throwModuleInitError", js.StringLiteral(decodedName)) + genCallHelper(VarField.throwModuleInitError, js.StringLiteral(decodedName)) }, js.Skip())) } val body = js.Block(initBlock, js.Return(moduleInstanceVar)) - globalFunctionDef("m", className, Nil, None, body) + globalFunctionDef(VarField.m, className, Nil, None, body) } createAccessor.map(createModuleInstanceField :: _) @@ -1062,7 +1062,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { genAssignToNoModuleExportVar(exportName, exportedValue) case ModuleKind.ESModule => - val field = fileLevelVar("e", exportName) + val field = fileLevelVar(VarField.e, exportName) val let = js.Let(field.ident, mutable = true, Some(exportedValue)) val exportStat = js.Export((field.ident -> js.ExportName(exportName)) :: Nil) WithGlobals(js.Block(let, exportStat)) @@ -1103,10 +1103,10 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { /* Initial value of the export. Updates are taken care of explicitly * when we assign to the static field. */ - genAssignToNoModuleExportVar(exportName, globalVar("t", varScope)) + genAssignToNoModuleExportVar(exportName, globalVar(VarField.t, varScope)) case ModuleKind.ESModule => - WithGlobals(globalVarExport("t", varScope, js.ExportName(exportName))) + WithGlobals(globalVarExport(VarField.t, varScope, js.ExportName(exportName))) case ModuleKind.CommonJSModule => globalRef("exports").flatMap { exportsVarRef => @@ -1115,7 +1115,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { js.StringLiteral(exportName), List( "get" -> js.Function(arrow = false, Nil, None, { - js.Return(globalVar("t", varScope)) + js.Return(globalVar(VarField.t, varScope)) }), "configurable" -> js.BooleanLiteral(true) ) @@ -1134,14 +1134,14 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) { ModuleInitializerImpl.fromInitializer(initializer) match { case VoidMainMethod(className, mainMethodName) => - WithGlobals(js.Apply(globalVar("s", (className, mainMethodName)), Nil)) + WithGlobals(js.Apply(globalVar(VarField.s, (className, mainMethodName)), Nil)) case MainMethodWithArgs(className, mainMethodName, args) => val stringArrayTypeRef = ArrayTypeRef(ClassRef(BoxedStringClass), 1) val argsArrayWithGlobals = genArrayValue(stringArrayTypeRef, args.map(js.StringLiteral(_))) for (argsArray <- argsArrayWithGlobals) yield { - js.Apply(globalVar("s", (className, mainMethodName)), argsArray :: Nil) + js.Apply(globalVar(VarField.s, (className, mainMethodName)), argsArray :: Nil) } } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLib.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLib.scala index 790ccfab2f..8a04956ad8 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLib.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/CoreJSLib.scala @@ -164,7 +164,7 @@ private[emitter] object CoreJSLib { str("fileLevelThis") -> This() ))) - extractWithGlobals(globalVarDef("linkingInfo", CoreVar, linkingInfo)) + extractWithGlobals(globalVarDef(VarField.linkingInfo, CoreVar, linkingInfo)) } private def defineJSBuiltinsSnapshotsAndPolyfills(): List[Tree] = { @@ -503,21 +503,21 @@ private[emitter] object CoreJSLib { // NamespaceGlobalVar.builtinName || polyfill genIdentBracketSelect(globalRef(builtin.namespaceGlobalVar), builtin.builtinName) || polyfill } - extractWithGlobals(globalVarDef(builtin.builtinName, CoreVar, rhs)) + extractWithGlobals(globalVarDef(builtin.polyfillField, CoreVar, rhs)) } } private def declareCachedL0(): List[Tree] = { condDefs(!allowBigIntsForLongs)( - extractWithGlobals(globalVarDecl("L0", CoreVar)) + extractWithGlobals(globalVarDecl(VarField.L0, CoreVar)) ) } private def assignCachedL0(): List[Tree] = { condDefs(!allowBigIntsForLongs)(List( - globalVar("L0", CoreVar) := genScalaClassNew( + globalVar(VarField.L0, CoreVar) := genScalaClassNew( LongImpl.RuntimeLongClass, LongImpl.initFromParts, 0, 0), - genClassDataOf(LongRef) DOT "zero" := globalVar("L0", CoreVar) + genClassDataOf(LongRef) DOT "zero" := globalVar(VarField.L0, CoreVar) )) } @@ -532,7 +532,7 @@ private[emitter] object CoreJSLib { * Closure) but we must still get hold of a string of that name for * runtime reflection. */ - defineFunction1("propertyName") { obj => + defineFunction1(VarField.propertyName) { obj => val prop = varRef("prop") ForIn(genEmptyImmutableLet(prop.ident), obj, Return(prop)) } @@ -554,10 +554,10 @@ private[emitter] object CoreJSLib { } if (useClassesForRegularClasses) { - extractWithGlobals(globalClassDef("Char", CoreVar, None, ctor :: toStr :: Nil)) + extractWithGlobals(globalClassDef(VarField.Char, CoreVar, None, ctor :: toStr :: Nil)) } else { - defineFunction("Char", ctor.args, ctor.body) ::: - assignES5ClassMembers(globalVar("Char", CoreVar), List(toStr)) + defineFunction(VarField.Char, ctor.args, ctor.body) ::: + assignES5ClassMembers(globalVar(VarField.Char, CoreVar), List(toStr)) } } @@ -567,7 +567,7 @@ private[emitter] object CoreJSLib { * This helper is never called for `value === null`. As implemented, * it would return `"object"` if it were. */ - defineFunction1("valueDescription") { value => + defineFunction1(VarField.valueDescription) { value => Return { If(typeof(value) === str("number"), { If((value === 0) && (int(1) / value < 0), { @@ -601,25 +601,25 @@ private[emitter] object CoreJSLib { ) ::: condDefs(asInstanceOfs != CheckedBehavior.Unchecked)( - defineFunction2("throwClassCastException") { (instance, classFullName) => + defineFunction2(VarField.throwClassCastException) { (instance, classFullName) => Throw(maybeWrapInUBE(asInstanceOfs, { genScalaClassNew(ClassCastExceptionClass, StringArgConstructorName, - genCallHelper("valueDescription", instance) + str(" cannot be cast to ") + classFullName) + genCallHelper(VarField.valueDescription, instance) + str(" cannot be cast to ") + classFullName) })) } ::: - defineFunction3("throwArrayCastException") { (instance, classArrayEncodedName, depth) => + defineFunction3(VarField.throwArrayCastException) { (instance, classArrayEncodedName, depth) => Block( While(depth.prefix_--, { classArrayEncodedName := (str("[") + classArrayEncodedName) }), - genCallHelper("throwClassCastException", instance, classArrayEncodedName) + genCallHelper(VarField.throwClassCastException, instance, classArrayEncodedName) ) } ) ::: condDefs(arrayIndexOutOfBounds != CheckedBehavior.Unchecked)( - defineFunction1("throwArrayIndexOutOfBoundsException") { i => + defineFunction1(VarField.throwArrayIndexOutOfBoundsException) { i => Throw(maybeWrapInUBE(arrayIndexOutOfBounds, { genScalaClassNew(ArrayIndexOutOfBoundsExceptionClass, StringArgConstructorName, @@ -629,17 +629,17 @@ private[emitter] object CoreJSLib { ) ::: condDefs(arrayStores != CheckedBehavior.Unchecked)( - defineFunction1("throwArrayStoreException") { v => + defineFunction1(VarField.throwArrayStoreException) { v => Throw(maybeWrapInUBE(arrayStores, { genScalaClassNew(ArrayStoreExceptionClass, StringArgConstructorName, - If(v === Null(), Null(), genCallHelper("valueDescription", v))) + If(v === Null(), Null(), genCallHelper(VarField.valueDescription, v))) })) } ) ::: condDefs(negativeArraySizes != CheckedBehavior.Unchecked)( - defineFunction0("throwNegativeArraySizeException") { + defineFunction0(VarField.throwNegativeArraySizeException) { Throw(maybeWrapInUBE(negativeArraySizes, { genScalaClassNew(NegativeArraySizeExceptionClass, NoArgConstructorName) @@ -648,7 +648,7 @@ private[emitter] object CoreJSLib { ) ::: condDefs(moduleInit == CheckedBehavior.Fatal)( - defineFunction1("throwModuleInitError") { name => + defineFunction1(VarField.throwModuleInitError) { name => Throw(genScalaClassNew(UndefinedBehaviorErrorClass, StringArgConstructorName, str("Initializer of ") + name + str(" called before completion of its super constructor"))) @@ -656,31 +656,31 @@ private[emitter] object CoreJSLib { ) ::: condDefs(nullPointers != CheckedBehavior.Unchecked)( - defineFunction0("throwNullPointerException") { + defineFunction0(VarField.throwNullPointerException) { Throw(maybeWrapInUBE(nullPointers, { genScalaClassNew(NullPointerExceptionClass, NoArgConstructorName) })) } ::: // "checkNotNull", but with a very short name - defineFunction1("n") { x => + defineFunction1(VarField.n) { x => Block( - If(x === Null(), genCallHelper("throwNullPointerException")), + If(x === Null(), genCallHelper(VarField.throwNullPointerException)), Return(x) ) } ) ::: - defineFunction1("noIsInstance") { instance => + defineFunction1(VarField.noIsInstance) { instance => Throw(New(TypeErrorRef, str("Cannot call isInstance() on a Class representing a JS trait/object") :: Nil)) } ::: - defineFunction2("newArrayObject") { (arrayClassData, lengths) => - Return(genCallHelper("newArrayObjectInternal", arrayClassData, lengths, int(0))) + defineFunction2(VarField.newArrayObject) { (arrayClassData, lengths) => + Return(genCallHelper(VarField.newArrayObjectInternal, arrayClassData, lengths, int(0))) } ::: - defineFunction3("newArrayObjectInternal") { (arrayClassData, lengths, lengthIndex) => + defineFunction3(VarField.newArrayObjectInternal) { (arrayClassData, lengths, lengthIndex) => val result = varRef("result") val subArrayClassData = varRef("subArrayClassData") val subLengthIndex = varRef("subLengthIndex") @@ -696,14 +696,14 @@ private[emitter] object CoreJSLib { const(underlying, result.u), For(let(i, 0), i < underlying.length, i.++, { BracketSelect(underlying, i) := - genCallHelper("newArrayObjectInternal", subArrayClassData, lengths, subLengthIndex) + genCallHelper(VarField.newArrayObjectInternal, subArrayClassData, lengths, subLengthIndex) }) )), Return(result) ) } ::: - defineFunction1("objectClone") { instance => + defineFunction1(VarField.objectClone) { instance => // return Object.create(Object.getPrototypeOf(instance), $getOwnPropertyDescriptors(instance)); val callGetOwnPropertyDescriptors = genCallPolyfillableBuiltin( GetOwnPropertyDescriptorsBuiltin, instance) @@ -712,18 +712,18 @@ private[emitter] object CoreJSLib { callGetOwnPropertyDescriptors))) } ::: - defineFunction1("objectOrArrayClone") { instance => + defineFunction1(VarField.objectOrArrayClone) { instance => // return instance.$classData.isArrayClass ? instance.clone__O() : $objectClone(instance); Return(If(genIdentBracketSelect(instance DOT classData, "isArrayClass"), Apply(instance DOT genName(cloneMethodName), Nil), - genCallHelper("objectClone", instance))) + genCallHelper(VarField.objectClone, instance))) } ) private def defineObjectGetClassFunctions(): List[Tree] = { // objectGetClass and objectClassName - def defineObjectGetClassBasedFun(name: String, + def defineObjectGetClassBasedFun(name: VarField, constantClassResult: ClassName => Tree, scalaObjectResult: VarRef => Tree, jsObjectResult: Tree): List[Tree] = { defineFunction1(name) { instance => @@ -733,7 +733,7 @@ private[emitter] object CoreJSLib { }, str("number") -> { Block( - If(genCallHelper("isInt", instance), { + If(genCallHelper(VarField.isInt, instance), { If((instance << 24 >> 24) === instance, { Return(constantClassResult(BoxedByteClass)) }, { @@ -745,7 +745,7 @@ private[emitter] object CoreJSLib { }) }, { if (strictFloats) { - If(genCallHelper("isFloat", instance), { + If(genCallHelper(VarField.isFloat, instance), { Return(constantClassResult(BoxedFloatClass)) }, { Return(constantClassResult(BoxedDoubleClass)) @@ -767,7 +767,7 @@ private[emitter] object CoreJSLib { if (nullPointers == CheckedBehavior.Unchecked) Return(Apply(instance DOT genName(getClassMethodName), Nil)) else - genCallHelper("throwNullPointerException") + genCallHelper(VarField.throwNullPointerException) }, { If(genIsInstanceOfHijackedClass(instance, BoxedLongClass), { Return(constantClassResult(BoxedLongClass)) @@ -797,13 +797,13 @@ private[emitter] object CoreJSLib { * (i.e., through a `ClassOf` node). */ condDefs(globalKnowledge.isClassClassInstantiated)( - defineObjectGetClassBasedFun("objectGetClass", + defineObjectGetClassBasedFun(VarField.objectGetClass, className => genClassOf(className), instance => Apply(instance DOT classData DOT "getClassOf", Nil), Null() ) ) ::: - defineObjectGetClassBasedFun("objectClassName", + defineObjectGetClassBasedFun(VarField.objectClassName, { className => StringLiteral(RuntimeClassNameMapperImpl.map( semantics.runtimeClassNameMapper, className.nameString)) @@ -813,7 +813,7 @@ private[emitter] object CoreJSLib { if (nullPointers == CheckedBehavior.Unchecked) Apply(Null() DOT genName(getNameMethodName), Nil) else - genCallHelper("throwNullPointerException") + genCallHelper(VarField.throwNullPointerException) } ) } @@ -823,8 +823,8 @@ private[emitter] object CoreJSLib { def defineDispatcher(methodName: MethodName, args: List[VarRef], body: Tree): List[Tree] = { - defineFunction("dp_" + genName(methodName), - paramList((instance :: args): _*), body) + val params = paramList((instance :: args): _*) + extractWithGlobals(globalFunctionDef(VarField.dp, methodName, params, None, body)) } /* A standard dispatcher performs a type test on the instance and then @@ -854,9 +854,9 @@ private[emitter] object CoreJSLib { def genHijackedMethodApply(className: ClassName): Tree = { val instanceAsPrimitive = - if (className == BoxedCharacterClass) genCallHelper("uC", instance) + if (className == BoxedCharacterClass) genCallHelper(VarField.uC, instance) else instance - Apply(globalVar("f", (className, methodName)), instanceAsPrimitive :: args) + Apply(globalVar(VarField.f, (className, methodName)), instanceAsPrimitive :: args) } def genBodyNoSwitch(hijackedClasses: List[ClassName]): Tree = { @@ -872,7 +872,7 @@ private[emitter] object CoreJSLib { if (implementedInObject) { val staticObjectCall: Tree = { - val fun = globalVar("c", ObjectClass).prototype DOT genName(methodName) + val fun = globalVar(VarField.c, ObjectClass).prototype DOT genName(methodName) Return(Apply(fun DOT "call", instance :: args)) } @@ -929,21 +929,21 @@ private[emitter] object CoreJSLib { def wrapBigInt64(tree: Tree): Tree = Apply(genIdentBracketSelect(BigIntRef, "asIntN"), 64 :: tree :: Nil) - defineFunction2("intDiv") { (x, y) => + defineFunction2(VarField.intDiv) { (x, y) => If(y === 0, throwDivByZero, { Return((x / y) | 0) }) } ::: - defineFunction2("intMod") { (x, y) => + defineFunction2(VarField.intMod) { (x, y) => If(y === 0, throwDivByZero, { Return((x % y) | 0) }) } ::: - defineFunction1("doubleToInt") { x => + defineFunction1(VarField.doubleToInt) { x => Return(If(x > 2147483647, 2147483647, If(x < -2147483648, -2147483648, x | 0))) } ::: condDefs(semantics.stringIndexOutOfBounds != CheckedBehavior.Unchecked)( - defineFunction2("charAt") { (s, i) => + defineFunction2(VarField.charAt) { (s, i) => val r = varRef("r") val throwStringIndexOutOfBoundsException = { @@ -958,18 +958,18 @@ private[emitter] object CoreJSLib { } ) ::: condDefs(allowBigIntsForLongs)( - defineFunction2("longDiv") { (x, y) => + defineFunction2(VarField.longDiv) { (x, y) => If(y === bigInt(0), throwDivByZero, { Return(wrapBigInt64(x / y)) }) } ::: - defineFunction2("longMod") { (x, y) => + defineFunction2(VarField.longMod) { (x, y) => If(y === bigInt(0), throwDivByZero, { Return(wrapBigInt64(x % y)) }) } ::: - defineFunction1("doubleToLong")(x => Return { + defineFunction1(VarField.doubleToLong)(x => Return { If(x < double(-9223372036854775808.0), { // -2^63 bigInt(-9223372036854775808L) }, { @@ -986,7 +986,7 @@ private[emitter] object CoreJSLib { }) }) ::: - defineFunction1("longToFloat") { x => + defineFunction1(VarField.longToFloat) { x => val abs = varRef("abs") val y = varRef("y") val absR = varRef("absR") @@ -1008,7 +1008,7 @@ private[emitter] object CoreJSLib { private def defineES2015LikeHelpers(): List[Tree] = ( condDefs(esVersion < ESVersion.ES2015)( - defineFunction2("newJSObjectWithVarargs") { (ctor, args) => + defineFunction2(VarField.newJSObjectWithVarargs) { (ctor, args) => val instance = varRef("instance") val result = varRef("result") @@ -1024,7 +1024,7 @@ private[emitter] object CoreJSLib { } ) ::: - defineFunction2("resolveSuperRef") { (superClass, propName) => + defineFunction2(VarField.resolveSuperRef) { (superClass, propName) => val getPrototypeOf = varRef("getPrototypeOf") val getOwnPropertyDescriptor = varRef("getOwnPropertyDescriptor") val superProto = varRef("superProto") @@ -1042,12 +1042,12 @@ private[emitter] object CoreJSLib { ) } ::: - defineFunction3("superGet") { (superClass, self, propName) => + defineFunction3(VarField.superGet) { (superClass, self, propName) => val desc = varRef("desc") val getter = varRef("getter") Block( - const(desc, genCallHelper("resolveSuperRef", superClass, propName)), + const(desc, genCallHelper(VarField.resolveSuperRef, superClass, propName)), If(desc !== Undefined(), Block( const(getter, genIdentBracketSelect(desc, "get")), Return(If(getter !== Undefined(), @@ -1057,12 +1057,12 @@ private[emitter] object CoreJSLib { ) } ::: - defineFunction4("superSet") { (superClass, self, propName, value) => + defineFunction4(VarField.superSet) { (superClass, self, propName, value) => val desc = varRef("desc") val setter = varRef("setter") Block( - const(desc, genCallHelper("resolveSuperRef", superClass, propName)), + const(desc, genCallHelper(VarField.resolveSuperRef, superClass, propName)), If(desc !== Undefined(), Block( const(setter, genIdentBracketSelect(desc, "set")), If(setter !== Undefined(), Block( @@ -1078,7 +1078,7 @@ private[emitter] object CoreJSLib { private def defineModuleHelpers(): List[Tree] = { condDefs(moduleKind == ModuleKind.CommonJSModule)( - defineFunction1("moduleDefault") { m => + defineFunction1(VarField.moduleDefault) { m => Return(If( m && (typeof(m) === str("object")) && (str("default") in m), BracketSelect(m, str("default")), @@ -1089,20 +1089,20 @@ private[emitter] object CoreJSLib { private def defineIntrinsics(): List[Tree] = ( condDefs(arrayIndexOutOfBounds != CheckedBehavior.Unchecked)( - defineFunction5("arraycopyCheckBounds") { (srcLen, srcPos, destLen, destPos, length) => + defineFunction5(VarField.arraycopyCheckBounds) { (srcLen, srcPos, destLen, destPos, length) => If((srcPos < 0) || (destPos < 0) || (length < 0) || (srcPos > ((srcLen - length) | 0)) || (destPos > ((destLen - length) | 0)), { - genCallHelper("throwArrayIndexOutOfBoundsException", Null()) + genCallHelper(VarField.throwArrayIndexOutOfBoundsException, Null()) }) } ) ::: - defineFunction5("arraycopyGeneric") { (srcArray, srcPos, destArray, destPos, length) => + defineFunction5(VarField.arraycopyGeneric) { (srcArray, srcPos, destArray, destPos, length) => val i = varRef("i") Block( if (arrayIndexOutOfBounds != CheckedBehavior.Unchecked) { - genCallHelper("arraycopyCheckBounds", srcArray.length, + genCallHelper(VarField.arraycopyCheckBounds, srcArray.length, srcPos, destArray.length, destPos, length) } else { Skip() @@ -1120,23 +1120,23 @@ private[emitter] object CoreJSLib { } ::: condDefs(esVersion < ESVersion.ES2015)( - defineFunction5("systemArraycopy") { (src, srcPos, dest, destPos, length) => - genCallHelper("arraycopyGeneric", src.u, srcPos, dest.u, destPos, length) + defineFunction5(VarField.systemArraycopy) { (src, srcPos, dest, destPos, length) => + genCallHelper(VarField.arraycopyGeneric, src.u, srcPos, dest.u, destPos, length) } ) ::: condDefs(esVersion >= ESVersion.ES2015 && nullPointers != CheckedBehavior.Unchecked)( - defineFunction5("systemArraycopy") { (src, srcPos, dest, destPos, length) => + defineFunction5(VarField.systemArraycopy) { (src, srcPos, dest, destPos, length) => Apply(src DOT "copyTo", List(srcPos, dest, destPos, length)) } ) ::: condDefs(arrayStores != CheckedBehavior.Unchecked)( - defineFunction5("systemArraycopyRefs") { (src, srcPos, dest, destPos, length) => + defineFunction5(VarField.systemArraycopyRefs) { (src, srcPos, dest, destPos, length) => If(Apply(genIdentBracketSelect(dest DOT classData, "isAssignableFrom"), List(src DOT classData)), { /* Fast-path, no need for array store checks. This always applies * for arrays of the same type, and a fortiori, when `src eq dest`. */ - genCallHelper("arraycopyGeneric", src.u, srcPos, dest.u, destPos, length) + genCallHelper(VarField.arraycopyGeneric, src.u, srcPos, dest.u, destPos, length) }, { /* Slow copy with "set" calls for every element. By construction, * we have `src ne dest` in this case. @@ -1146,7 +1146,7 @@ private[emitter] object CoreJSLib { Block( const(srcArray, src.u), condTree(arrayIndexOutOfBounds != CheckedBehavior.Unchecked) { - genCallHelper("arraycopyCheckBounds", srcArray.length, + genCallHelper(VarField.arraycopyCheckBounds, srcArray.length, srcPos, dest.u.length, destPos, length) }, For(let(i, 0), i < length, i := ((i + 1) | 0), { @@ -1156,8 +1156,8 @@ private[emitter] object CoreJSLib { }) } ::: - defineFunction5("systemArraycopyFull") { (src, srcPos, dest, destPos, length) => - val ObjectArray = globalVar("ac", ObjectClass) + defineFunction5(VarField.systemArraycopyFull) { (src, srcPos, dest, destPos, length) => + val ObjectArray = globalVar(VarField.ac, ObjectClass) val srcData = varRef("srcData") Block( @@ -1168,16 +1168,16 @@ private[emitter] object CoreJSLib { // Fast path: the values are array of the same type genUncheckedArraycopy(List(src, srcPos, dest, destPos, length)) }, { - genCallHelper("throwArrayStoreException", Null()) + genCallHelper(VarField.throwArrayStoreException, Null()) }) }, { /* src and dest are of different types; the only situation that * can still be valid is if they are two reference array types. */ If((src instanceof ObjectArray) && (dest instanceof ObjectArray), { - genCallHelper("systemArraycopyRefs", src, srcPos, dest, destPos, length) + genCallHelper(VarField.systemArraycopyRefs, src, srcPos, dest, destPos, length) }, { - genCallHelper("throwArrayStoreException", Null()) + genCallHelper(VarField.throwArrayStoreException, Null()) }) }) ) @@ -1188,8 +1188,8 @@ private[emitter] object CoreJSLib { locally { val WeakMapRef = globalRef("WeakMap") - val lastIDHash = fileLevelVar("lastIDHash") - val idHashCodeMap = fileLevelVar("idHashCodeMap") + val lastIDHash = fileLevelVar(VarField.lastIDHash) + val idHashCodeMap = fileLevelVar(VarField.idHashCodeMap) val obj = varRef("obj") val biHash = varRef("biHash") @@ -1198,7 +1198,7 @@ private[emitter] object CoreJSLib { def functionSkeleton(defaultImpl: Tree): Function = { def genHijackedMethodApply(className: ClassName, arg: Tree): Tree = - Apply(globalVar("f", (className, hashCodeMethodName)), arg :: Nil) + Apply(globalVar(VarField.f, (className, hashCodeMethodName)), arg :: Nil) def genReturnHijackedMethodApply(className: ClassName): Tree = Return(genHijackedMethodApply(className, obj)) @@ -1323,9 +1323,9 @@ private[emitter] object CoreJSLib { ) ::: ( if (esVersion >= ESVersion.ES2015) { val f = weakMapBasedFunction - defineFunction("systemIdentityHashCode", f.args, f.body) + defineFunction(VarField.systemIdentityHashCode, f.args, f.body) } else { - extractWithGlobals(globalVarDef("systemIdentityHashCode", CoreVar, + extractWithGlobals(globalVarDef(VarField.systemIdentityHashCode, CoreVar, If(idHashCodeMap !== Null(), weakMapBasedFunction, fieldBasedFunction))) } ) @@ -1333,24 +1333,24 @@ private[emitter] object CoreJSLib { ) private def defineIsPrimitiveFunctions(): List[Tree] = { - def defineIsIntLike(name: String, specificTest: VarRef => Tree): List[Tree] = { + def defineIsIntLike(name: VarField, specificTest: VarRef => Tree): List[Tree] = { defineFunction1(name) { v => Return((typeof(v) === str("number")) && specificTest(v) && ((int(1) / v) !== (int(1) / double(-0.0)))) } } - defineIsIntLike("isByte", v => (v << 24 >> 24) === v) ::: - defineIsIntLike("isShort", v => (v << 16 >> 16) === v) ::: - defineIsIntLike("isInt", v => (v | 0) === v) ::: + defineIsIntLike(VarField.isByte, v => (v << 24 >> 24) === v) ::: + defineIsIntLike(VarField.isShort, v => (v << 16 >> 16) === v) ::: + defineIsIntLike(VarField.isInt, v => (v | 0) === v) ::: condDefs(allowBigIntsForLongs)( - defineFunction1("isLong") { v => + defineFunction1(VarField.isLong) { v => Return((typeof(v) === str("bigint")) && (Apply(genIdentBracketSelect(BigIntRef, "asIntN"), int(64) :: v :: Nil) === v)) } ) ::: condDefs(strictFloats)( - defineFunction1("isFloat") { v => + defineFunction1(VarField.isFloat) { v => Return((typeof(v) === str("number")) && ((v !== v) || (genCallPolyfillableBuiltin(FroundBuiltin, v) === v))) } @@ -1359,46 +1359,46 @@ private[emitter] object CoreJSLib { private def defineBoxFunctions(): List[Tree] = ( // Boxes for Chars - defineFunction1("bC") { c => - Return(New(globalVar("Char", CoreVar), c :: Nil)) + defineFunction1(VarField.bC) { c => + Return(New(globalVar(VarField.Char, CoreVar), c :: Nil)) } ::: - extractWithGlobals(globalVarDef("bC0", CoreVar, genCallHelper("bC", 0))) + extractWithGlobals(globalVarDef(VarField.bC0, CoreVar, genCallHelper(VarField.bC, 0))) ) ::: ( if (asInstanceOfs != CheckedBehavior.Unchecked) { // Unboxes for everything - def defineUnbox(name: String, boxedClassName: ClassName, resultExpr: VarRef => Tree): List[Tree] = { + def defineUnbox(name: VarField, boxedClassName: ClassName, resultExpr: VarRef => Tree): List[Tree] = { val fullName = boxedClassName.nameString defineFunction1(name)(v => Return { If(genIsInstanceOfHijackedClass(v, boxedClassName) || (v === Null()), resultExpr(v), - genCallHelper("throwClassCastException", v, str(fullName))) + genCallHelper(VarField.throwClassCastException, v, str(fullName))) }) } ( - defineUnbox("uV", BoxedUnitClass, _ => Undefined()) ::: - defineUnbox("uZ", BoxedBooleanClass, v => !(!v)) ::: - defineUnbox("uC", BoxedCharacterClass, v => If(v === Null(), 0, v DOT "c")) ::: - defineUnbox("uB", BoxedByteClass, _ | 0) ::: - defineUnbox("uS", BoxedShortClass, _ | 0) ::: - defineUnbox("uI", BoxedIntegerClass, _ | 0) ::: - defineUnbox("uJ", BoxedLongClass, v => If(v === Null(), genLongZero(), v)) ::: + defineUnbox(VarField.uV, BoxedUnitClass, _ => Undefined()) ::: + defineUnbox(VarField.uZ, BoxedBooleanClass, v => !(!v)) ::: + defineUnbox(VarField.uC, BoxedCharacterClass, v => If(v === Null(), 0, v DOT "c")) ::: + defineUnbox(VarField.uB, BoxedByteClass, _ | 0) ::: + defineUnbox(VarField.uS, BoxedShortClass, _ | 0) ::: + defineUnbox(VarField.uI, BoxedIntegerClass, _ | 0) ::: + defineUnbox(VarField.uJ, BoxedLongClass, v => If(v === Null(), genLongZero(), v)) ::: /* Since the type test ensures that v is either null or a float, we can * use + instead of fround. */ - defineUnbox("uF", BoxedFloatClass, v => +v) ::: + defineUnbox(VarField.uF, BoxedFloatClass, v => +v) ::: - defineUnbox("uD", BoxedDoubleClass, v => +v) ::: - defineUnbox("uT", BoxedStringClass, v => If(v === Null(), StringLiteral(""), v)) + defineUnbox(VarField.uD, BoxedDoubleClass, v => +v) ::: + defineUnbox(VarField.uT, BoxedStringClass, v => If(v === Null(), StringLiteral(""), v)) ) } else { // Unboxes for Chars and Longs ( - defineFunction1("uC") { v => + defineFunction1(VarField.uC) { v => Return(If(v === Null(), 0, v DOT "c")) } ::: - defineFunction1("uJ") { v => + defineFunction1(VarField.uJ) { v => Return(If(v === Null(), genLongZero(), v)) } ) @@ -1412,7 +1412,7 @@ private[emitter] object CoreJSLib { */ private def defineSpecializedArrayClasses(): List[Tree] = { specializedArrayTypeRefs.flatMap { componentTypeRef => - val ArrayClass = globalVar("ac", componentTypeRef) + val ArrayClass = globalVar(VarField.ac, componentTypeRef) val isArrayOfObject = componentTypeRef == ClassRef(ObjectClass) val isTypedArray = usesUnderlyingTypedArray(componentTypeRef) @@ -1433,7 +1433,7 @@ private[emitter] object CoreJSLib { val boundsCheck = { If((i < 0) || (i >= This().u.length), - genCallHelper("throwArrayIndexOutOfBoundsException", i)) + genCallHelper(VarField.throwArrayIndexOutOfBoundsException, i)) } List( @@ -1476,7 +1476,7 @@ private[emitter] object CoreJSLib { if (isTypedArray) { Block( if (semantics.arrayIndexOutOfBounds != CheckedBehavior.Unchecked) { - genCallHelper("arraycopyCheckBounds", This().u.length, + genCallHelper(VarField.arraycopyCheckBounds, This().u.length, srcPos, dest.u.length, destPos, length) } else { Skip() @@ -1487,7 +1487,7 @@ private[emitter] object CoreJSLib { Nil) ) } else { - genCallHelper("arraycopyGeneric", This().u, srcPos, + genCallHelper(VarField.arraycopyGeneric, This().u, srcPos, dest.u, destPos, length) } }) @@ -1504,13 +1504,13 @@ private[emitter] object CoreJSLib { val members = getAndSet ::: copyTo ::: clone :: Nil if (useClassesForRegularClasses) { - extractWithGlobals(globalClassDef("ac", componentTypeRef, - Some(globalVar("c", ObjectClass)), ctor :: members)) + extractWithGlobals(globalClassDef(VarField.ac, componentTypeRef, + Some(globalVar(VarField.c, ObjectClass)), ctor :: members)) } else { val clsDef = { - extractWithGlobals(globalFunctionDef("ac", componentTypeRef, + extractWithGlobals(globalFunctionDef(VarField.ac, componentTypeRef, ctor.args, ctor.restParam, ctor.body)) ::: - (ArrayClass.prototype := New(globalVar("h", ObjectClass), Nil)) :: + (ArrayClass.prototype := New(globalVar(VarField.h, ObjectClass), Nil)) :: (ArrayClass.prototype DOT "constructor" := ArrayClass) :: assignES5ClassMembers(ArrayClass, members) } @@ -1518,8 +1518,8 @@ private[emitter] object CoreJSLib { componentTypeRef match { case _: ClassRef => clsDef ::: - extractWithGlobals(globalFunctionDef("ah", ObjectClass, Nil, None, Skip())) ::: - (globalVar("ah", ObjectClass).prototype := ArrayClass.prototype) :: Nil + extractWithGlobals(globalFunctionDef(VarField.ah, ObjectClass, Nil, None, Skip())) ::: + (globalVar(VarField.ah, ObjectClass).prototype := ArrayClass.prototype) :: Nil case _: PrimRef => clsDef } @@ -1533,7 +1533,7 @@ private[emitter] object CoreJSLib { If(typeof(arg) === str("number"), { val arraySizeCheck = condTree(negativeArraySizes != CheckedBehavior.Unchecked) { - If(arg < 0, genCallHelper("throwNegativeArraySizeException")) + If(arg < 0, genCallHelper(VarField.throwNegativeArraySizeException)) } getArrayUnderlyingTypedArrayClassRef(componentTypeRef) match { @@ -1624,7 +1624,7 @@ private[emitter] object CoreJSLib { genArrowFunction(paramList(obj), Return(bool(false)))), If(arrayClass !== Undefined(), { // it is undefined for void privateFieldSet("_arrayOf", - Apply(New(globalVar("TypeData", CoreVar), Nil) DOT "initSpecializedArray", + Apply(New(globalVar(VarField.TypeData, CoreVar), Nil) DOT "initSpecializedArray", List(This(), arrayClass, typedArrayClass))) }), Return(This()) @@ -1648,7 +1648,7 @@ private[emitter] object CoreJSLib { paramList(internalNameObj, isInterface, fullName, ancestors, isJSType, parentData, isInstance), None, { Block( - const(internalName, genCallHelper("propertyName", internalNameObj)), + const(internalName, genCallHelper(VarField.propertyName, internalNameObj)), if (globalKnowledge.isParentDataAccessed) privateFieldSet("parentData", parentData) else @@ -1765,13 +1765,13 @@ private[emitter] object CoreJSLib { val boundsCheck = condTree(arrayIndexOutOfBounds != CheckedBehavior.Unchecked) { If((i < 0) || (i >= This().u.length), - genCallHelper("throwArrayIndexOutOfBoundsException", i)) + genCallHelper(VarField.throwArrayIndexOutOfBoundsException, i)) } val storeCheck = { If((v !== Null()) && !(componentData DOT "isJSType") && !Apply(genIdentBracketSelect(componentData, "isInstance"), v :: Nil), - genCallHelper("throwArrayStoreException", v)) + genCallHelper(VarField.throwArrayStoreException, v)) } List( @@ -1794,7 +1794,7 @@ private[emitter] object CoreJSLib { val length = varRef("length") val methodDef = MethodDef(static = false, Ident("copyTo"), paramList(srcPos, dest, destPos, length), None, { - genCallHelper("arraycopyGeneric", This().u, srcPos, + genCallHelper(VarField.arraycopyGeneric, This().u, srcPos, dest.u, destPos, length) }) methodDef :: Nil @@ -1810,12 +1810,12 @@ private[emitter] object CoreJSLib { val members = set ::: copyTo ::: clone :: Nil if (useClassesForRegularClasses) { - ClassDef(Some(ArrayClass.ident), Some(globalVar("ac", ObjectClass)), + ClassDef(Some(ArrayClass.ident), Some(globalVar(VarField.ac, ObjectClass)), ctor :: members) } else { Block( FunctionDef(ArrayClass.ident, ctor.args, ctor.restParam, ctor.body) :: - (ArrayClass.prototype := New(globalVar("ah", ObjectClass), Nil)) :: + (ArrayClass.prototype := New(globalVar(VarField.ah, ObjectClass), Nil)) :: (ArrayClass.prototype DOT "constructor" := ArrayClass) :: assignES5ClassMembers(ArrayClass, members) ) @@ -1865,7 +1865,7 @@ private[emitter] object CoreJSLib { Block( If(!(This() DOT "_arrayOf"), This() DOT "_arrayOf" := - Apply(New(globalVar("TypeData", CoreVar), Nil) DOT "initArray", This() :: Nil), + Apply(New(globalVar(VarField.TypeData, CoreVar), Nil) DOT "initArray", This() :: Nil), Skip()), Return(This() DOT "_arrayOf") ) @@ -1908,7 +1908,7 @@ private[emitter] object CoreJSLib { if (asInstanceOfs != CheckedBehavior.Unchecked) { If((obj !== Null()) && !(This() DOT "isJSType") && !Apply(genIdentBracketSelect(This(), "isInstance"), obj :: Nil), - genCallHelper("throwClassCastException", obj, genIdentBracketSelect(This(), "name")), + genCallHelper(VarField.throwClassCastException, obj, genIdentBracketSelect(This(), "name")), Skip()) } else { Skip() @@ -1943,7 +1943,7 @@ private[emitter] object CoreJSLib { For(let(i, 0), i < lengths.length, i.++, { arrayClassData := Apply(arrayClassData DOT "getArrayOf", Nil) }), - Return(genCallHelper("newArrayObject", arrayClassData, lengths)) + Return(genCallHelper(VarField.newArrayObject, arrayClassData, lengths)) ) }) } @@ -1974,10 +1974,10 @@ private[emitter] object CoreJSLib { ) if (useClassesForRegularClasses) { - extractWithGlobals(globalClassDef("TypeData", CoreVar, None, ctor :: members)) + extractWithGlobals(globalClassDef(VarField.TypeData, CoreVar, None, ctor :: members)) } else { - defineFunction("TypeData", ctor.args, ctor.body) ::: - assignES5ClassMembers(globalVar("TypeData", CoreVar), members) + defineFunction(VarField.TypeData, ctor.args, ctor.body) ::: + assignES5ClassMembers(globalVar(VarField.TypeData, CoreVar), members) } } @@ -1988,7 +1988,7 @@ private[emitter] object CoreJSLib { val data = varRef("data") val arrayDepth = varRef("arrayDepth") - val forObj = extractWithGlobals(globalFunctionDef("isArrayOf", ObjectClass, paramList(obj, depth), None, { + val forObj = extractWithGlobals(globalFunctionDef(VarField.isArrayOf, ObjectClass, paramList(obj, depth), None, { Block( const(data, obj && (obj DOT "$classData")), If(!data, { @@ -2009,7 +2009,7 @@ private[emitter] object CoreJSLib { val forPrims = orderedPrimRefsWithoutVoid.flatMap { primRef => val obj = varRef("obj") val depth = varRef("depth") - extractWithGlobals(globalFunctionDef("isArrayOf", primRef, paramList(obj, depth), None, { + extractWithGlobals(globalFunctionDef(VarField.isArrayOf, primRef, paramList(obj, depth), None, { Return(!(!(obj && (obj DOT classData) && ((obj DOT classData DOT "arrayDepth") === depth) && ((obj DOT classData DOT "arrayBase") === genClassDataOf(primRef))))) @@ -2029,11 +2029,11 @@ private[emitter] object CoreJSLib { val obj = varRef("obj") val depth = varRef("depth") - extractWithGlobals(globalFunctionDef("asArrayOf", typeRef, paramList(obj, depth), None, { - If(Apply(globalVar("isArrayOf", typeRef), obj :: depth :: Nil) || (obj === Null()), { + extractWithGlobals(globalFunctionDef(VarField.asArrayOf, typeRef, paramList(obj, depth), None, { + If(Apply(globalVar(VarField.isArrayOf, typeRef), obj :: depth :: Nil) || (obj === Null()), { Return(obj) }, { - genCallHelper("throwArrayCastException", obj, str(encodedName), depth) + genCallHelper(VarField.throwArrayCastException, obj, str(encodedName), depth) }) })) } @@ -2055,7 +2055,7 @@ private[emitter] object CoreJSLib { val that = varRef("that") val obj = varRef("obj") - val typeDataVar = globalVar("d", ObjectClass) + val typeDataVar = globalVar(VarField.d, ObjectClass) def privateFieldSet(fieldName: String, value: Tree): Tree = typeDataVar DOT fieldName := value @@ -2064,7 +2064,7 @@ private[emitter] object CoreJSLib { genIdentBracketSelect(typeDataVar, fieldName) := value extractWithGlobals( - globalVarDef("d", ObjectClass, New(globalVar("TypeData", CoreVar), Nil))) ::: + globalVarDef(VarField.d, ObjectClass, New(globalVar(VarField.TypeData, CoreVar), Nil))) ::: List( privateFieldSet("ancestors", ObjectConstr(List((Ident(genName(ObjectClass)) -> 1)))), privateFieldSet("arrayEncodedName", str("L" + fullName + ";")), @@ -2077,9 +2077,9 @@ private[emitter] object CoreJSLib { publicFieldSet("isInstance", genArrowFunction(paramList(obj), Return(obj !== Null()))), privateFieldSet("_arrayOf", { - Apply(New(globalVar("TypeData", CoreVar), Nil) DOT "initSpecializedArray", List( + Apply(New(globalVar(VarField.TypeData, CoreVar), Nil) DOT "initSpecializedArray", List( typeDataVar, - globalVar("ac", ObjectClass), + globalVar(VarField.ac, ObjectClass), Undefined(), // typedArray genArrowFunction(paramList(that), { val thatDepth = varRef("thatDepth") @@ -2094,7 +2094,7 @@ private[emitter] object CoreJSLib { }) )) }), - globalVar("c", ObjectClass).prototype DOT "$classData" := typeDataVar + globalVar(VarField.c, ObjectClass).prototype DOT "$classData" := typeDataVar ) } @@ -2119,8 +2119,8 @@ private[emitter] object CoreJSLib { Undefined() } - extractWithGlobals(globalVarDef("d", primRef, { - Apply(New(globalVar("TypeData", CoreVar), Nil) DOT "initPrim", + extractWithGlobals(globalVarDef(VarField.d, primRef, { + Apply(New(globalVar(VarField.TypeData, CoreVar), Nil) DOT "initPrim", List(zero, str(primRef.charCode.toString()), str(primRef.displayName), if (primRef == VoidRef) Undefined() @@ -2132,35 +2132,35 @@ private[emitter] object CoreJSLib { obj ::: prims } - private def defineFunction(name: String, args: List[ParamDef], body: Tree): List[Tree] = + private def defineFunction(name: VarField, args: List[ParamDef], body: Tree): List[Tree] = extractWithGlobals(globalFunctionDef(name, CoreVar, args, None, body)) private val argRefs = List.tabulate(5)(i => varRef("arg" + i)) - private def defineFunction0(name: String)(body: Tree): List[Tree] = + private def defineFunction0(name: VarField)(body: Tree): List[Tree] = defineFunction(name, Nil, body) - private def defineFunction1(name: String)(body: VarRef => Tree): List[Tree] = { + private def defineFunction1(name: VarField)(body: VarRef => Tree): List[Tree] = { val a :: _ = argRefs defineFunction(name, paramList(a), body(a)) } - private def defineFunction2(name: String)(body: (VarRef, VarRef) => Tree): List[Tree] = { + private def defineFunction2(name: VarField)(body: (VarRef, VarRef) => Tree): List[Tree] = { val a :: b :: _ = argRefs defineFunction(name, paramList(a, b), body(a, b)) } - private def defineFunction3(name: String)(body: (VarRef, VarRef, VarRef) => Tree): List[Tree] = { + private def defineFunction3(name: VarField)(body: (VarRef, VarRef, VarRef) => Tree): List[Tree] = { val a :: b :: c :: _ = argRefs defineFunction(name, paramList(a, b, c), body(a, b, c)) } - private def defineFunction4(name: String)(body: (VarRef, VarRef, VarRef, VarRef) => Tree): List[Tree] = { + private def defineFunction4(name: VarField)(body: (VarRef, VarRef, VarRef, VarRef) => Tree): List[Tree] = { val a :: b :: c :: d :: _ = argRefs defineFunction(name, paramList(a, b, c, d), body(a, b, c, d)) } - private def defineFunction5(name: String)(body: (VarRef, VarRef, VarRef, VarRef, VarRef) => Tree): List[Tree] = { + private def defineFunction5(name: VarField)(body: (VarRef, VarRef, VarRef, VarRef, VarRef) => Tree): List[Tree] = { val a :: b :: c :: d :: e :: _ = argRefs defineFunction(name, paramList(a, b, c, d, e), body(a, b, c, d, e)) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala index d0cd14d62c..c299d8fdd7 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/FunctionEmitter.scala @@ -400,7 +400,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { private def newSyntheticVar()(implicit pos: Position): js.Ident = { syntheticVarCounter += 1 - fileLevelVarIdent("$x" + syntheticVarCounter) + fileLevelVarIdent(VarField.x, syntheticVarCounter.toString()) } @inline @@ -482,7 +482,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { implicit pos: Position): WithGlobals[js.Function] = { performOptimisticThenPessimisticRuns { - val thisIdent = fileLevelVarIdent("thiz", thisOriginalName) + val thisIdent = fileLevelVarIdent(VarField.thiz, thisOriginalName) val env = env0.withExplicitThis() val js.Function(jsArrow, jsParams, restParam, jsBody) = desugarToFunctionInternal(arrow = false, params, None, body, isStat, env) @@ -667,7 +667,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { unnest(superClass, qualifier, item, rhs) { (newSuperClass, newQualifier, newItem, newRhs, env0) => implicit val env = env0 - genCallHelper("superSet", transformExprNoChar(newSuperClass), + genCallHelper(VarField.superSet, transformExprNoChar(newSuperClass), transformExprNoChar(newQualifier), transformExprNoChar(item), transformExprNoChar(rhs)) } @@ -678,7 +678,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { if (needToUseGloballyMutableVarSetter(scope)) { unnest(rhs) { (rhs, env0) => implicit val env = env0 - js.Apply(globalVar("u", scope), transformExpr(rhs, lhs.tpe) :: Nil) + js.Apply(globalVar(VarField.u, scope), transformExpr(rhs, lhs.tpe) :: Nil) } } else { // Assign normally. @@ -692,7 +692,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case StoreModule(className, value) => unnest(value) { (newValue, env0) => implicit val env = env0 - js.Assign(globalVar("n", className), transformExprNoChar(newValue)) + js.Assign(globalVar(VarField.n, className), transformExprNoChar(newValue)) } case While(cond, body) => @@ -773,7 +773,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { } else { val superCtor = { if (globalKnowledge.hasStoredSuperClass(enclosingClassName)) { - fileLevelVar("superClass") + fileLevelVar(VarField.superClass) } else { val superClass = globalKnowledge.getSuperClassOfJSClass(enclosingClassName) @@ -879,9 +879,9 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case (PrimArray(srcPrimRef), PrimArray(destPrimRef)) if srcPrimRef == destPrimRef => genUncheckedArraycopy(jsArgs) case (RefArray(), RefArray()) => - genCallHelper("systemArraycopyRefs", jsArgs: _*) + genCallHelper(VarField.systemArraycopyRefs, jsArgs: _*) case _ => - genCallHelper("systemArraycopyFull", jsArgs: _*) + genCallHelper(VarField.systemArraycopyFull, jsArgs: _*) } } } @@ -2209,7 +2209,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { genSelect(transformExprNoChar(checkNotNull(qualifier)), className, field) case SelectStatic(className, item) => - globalVar("t", (className, item.name)) + globalVar(VarField.t, (className, item.name)) case SelectJSNativeMember(className, member) => val jsNativeLoadSpec = @@ -2247,10 +2247,10 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { js.Apply(newReceiver(false) DOT transformMethodIdent(method), newArgs) def genDispatchApply(): js.Tree = - genCallHelper("dp_" + genName(methodName), newReceiver(false) :: newArgs: _*) + js.Apply(globalVar(VarField.dp, methodName), newReceiver(false) :: newArgs) def genHijackedMethodApply(className: ClassName): js.Tree = - genApplyStaticLike("f", className, method, newReceiver(className == BoxedCharacterClass) :: newArgs) + genApplyStaticLike(VarField.f, className, method, newReceiver(className == BoxedCharacterClass) :: newArgs) if (isMaybeHijackedClass(receiver.tpe) && !methodName.isReflectiveProxy) { @@ -2300,20 +2300,20 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { val transformedArgs = newReceiver :: newArgs if (flags.isConstructor) { - genApplyStaticLike("ct", className, method, transformedArgs) + genApplyStaticLike(VarField.ct, className, method, transformedArgs) } else if (flags.isPrivate) { - genApplyStaticLike("p", className, method, transformedArgs) + genApplyStaticLike(VarField.p, className, method, transformedArgs) } else if (globalKnowledge.isInterface(className)) { - genApplyStaticLike("f", className, method, transformedArgs) + genApplyStaticLike(VarField.f, className, method, transformedArgs) } else { val fun = - globalVar("c", className).prototype DOT transformMethodIdent(method) + globalVar(VarField.c, className).prototype DOT transformMethodIdent(method) js.Apply(fun DOT "call", transformedArgs) } case ApplyStatic(flags, className, method, args) => genApplyStaticLike( - if (flags.isPrivate) "ps" else "s", + if (flags.isPrivate) VarField.ps else VarField.s, className, method, transformTypedArgs(method.name, args)) @@ -2354,7 +2354,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { else genLongMethodApply(newLhs, LongImpl.toInt) case DoubleToInt => - genCallHelper("doubleToInt", newLhs) + genCallHelper(VarField.doubleToInt, newLhs) case DoubleToFloat => genFround(newLhs) @@ -2366,14 +2366,14 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { genLongMethodApply(newLhs, LongImpl.toDouble) case DoubleToLong => if (useBigIntForLongs) - genCallHelper("doubleToLong", newLhs) + genCallHelper(VarField.doubleToLong, newLhs) else genLongModuleApply(LongImpl.fromDouble, newLhs) // Long -> Float (neither widening nor narrowing) case LongToFloat => if (useBigIntForLongs) - genCallHelper("longToFloat", newLhs) + genCallHelper(VarField.longToFloat, newLhs) else genLongMethodApply(newLhs, LongImpl.toFloat) @@ -2458,14 +2458,14 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case IntLiteral(r) if r != 0 => or0(js.BinaryOp(JSBinaryOp./, newLhs, newRhs)) case _ => - genCallHelper("intDiv", newLhs, newRhs) + genCallHelper(VarField.intDiv, newLhs, newRhs) } case Int_% => rhs match { case IntLiteral(r) if r != 0 => or0(js.BinaryOp(JSBinaryOp.%, newLhs, newRhs)) case _ => - genCallHelper("intMod", newLhs, newRhs) + genCallHelper(VarField.intMod, newLhs, newRhs) } case Int_| => js.BinaryOp(JSBinaryOp.|, newLhs, newRhs) @@ -2513,7 +2513,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case LongLiteral(r) if r != 0L => wrapBigInt64(js.BinaryOp(JSBinaryOp./, newLhs, newRhs)) case _ => - genCallHelper("longDiv", newLhs, newRhs) + genCallHelper(VarField.longDiv, newLhs, newRhs) } } else { genLongMethodApply(newLhs, LongImpl./, newRhs) @@ -2524,7 +2524,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case LongLiteral(r) if r != 0L => wrapBigInt64(js.BinaryOp(JSBinaryOp.%, newLhs, newRhs)) case _ => - genCallHelper("longMod", newLhs, newRhs) + genCallHelper(VarField.longMod, newLhs, newRhs) } } else { genLongMethodApply(newLhs, LongImpl.%, newRhs) @@ -2631,7 +2631,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case String_charAt => semantics.stringIndexOutOfBounds match { case CheckedBehavior.Compliant | CheckedBehavior.Fatal => - genCallHelper("charAt", newLhs, newRhs) + genCallHelper(VarField.charAt, newLhs, newRhs) case CheckedBehavior.Unchecked => js.Apply(genIdentBracketSelect(newLhs, "charCodeAt"), List(newRhs)) } @@ -2672,7 +2672,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { extractWithGlobals(genAsInstanceOf(transformExprNoChar(expr), tpe)) case GetClass(expr) => - genCallHelper("objectGetClass", transformExprNoChar(expr)) + genCallHelper(VarField.objectGetClass, transformExprNoChar(expr)) case Clone(expr) => val newExpr = transformExprNoChar(checkNotNull(expr)) @@ -2700,15 +2700,15 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { */ case ClassType(CloneableClass) | ClassType(SerializableClass) | ClassType(ObjectClass) | AnyType => - genCallHelper("objectOrArrayClone", newExpr) + genCallHelper(VarField.objectOrArrayClone, newExpr) // Otherwise, it is known not to be an array. case _ => - genCallHelper("objectClone", newExpr) + genCallHelper(VarField.objectClone, newExpr) } case IdentityHashCode(expr) => - genCallHelper("systemIdentityHashCode", transformExprNoChar(expr)) + genCallHelper(VarField.systemIdentityHashCode, transformExprNoChar(expr)) case WrapAsThrowable(expr) => val newExpr = transformExprNoChar(expr).asInstanceOf[js.VarRef] @@ -2727,7 +2727,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { // Transients case Transient(CheckNotNull(obj)) => - genCallHelper("n", transformExpr(obj, preserveChar = true)) + genCallHelper(VarField.n, transformExpr(obj, preserveChar = true)) case Transient(AssumeNotNull(obj)) => transformExpr(obj, preserveChar = true) @@ -2753,7 +2753,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { } case Transient(ObjectClassName(obj)) => - genCallHelper("objectClassName", transformExprNoChar(obj)) + genCallHelper(VarField.objectClassName, transformExprNoChar(obj)) case Transient(ArrayToTypedArray(expr, primRef)) => val value = transformExprNoChar(checkNotNull(expr)) @@ -2800,7 +2800,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case Transient(JSNewVararg(constr, argsArray)) => assert(!es2015, s"generated a JSNewVargs with ES 2015+ at ${tree.pos}") - genCallHelper("newJSObjectWithVarargs", + genCallHelper(VarField.newJSObjectWithVarargs, transformExprNoChar(constr), transformExprNoChar(argsArray)) case JSPrivateSelect(qualifier, className, field) => @@ -2840,7 +2840,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { transformExprNoChar(method)), args.map(transformJSArg)) case JSSuperSelect(superClass, qualifier, item) => - genCallHelper("superGet", transformExprNoChar(superClass), + genCallHelper(VarField.superGet, transformExprNoChar(superClass), transformExprNoChar(qualifier), transformExprNoChar(item)) case JSImportCall(arg) => @@ -2902,7 +2902,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { js.UnaryOp(JSUnaryOp.typeof, transformExprNoChar(globalRef)) case JSLinkingInfo() => - globalVar("linkingInfo", CoreVar) + globalVar(VarField.linkingInfo, CoreVar) // Literals @@ -2943,10 +2943,10 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { js.This() case VarKind.ExplicitThisAlias => - fileLevelVar("thiz") + fileLevelVar(VarField.thiz) case VarKind.ClassCapture => - fileLevelVar("cc", genName(name.name)) + fileLevelVar(VarField.cc, genName(name.name)) } case Transient(JSVarRef(name, _)) => @@ -2954,7 +2954,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { case This() => if (env.hasExplicitThis) - fileLevelVar("thiz") + fileLevelVar(VarField.thiz) else js.This() @@ -2971,7 +2971,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { for ((value, expectedType) <- captureValues.zip(expectedTypes)) yield transformExpr(value, expectedType) } - js.Apply(globalVar("a", className), transformedArgs) + js.Apply(globalVar(VarField.a, className), transformedArgs) // Invalid trees @@ -2984,7 +2984,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { if (preserveChar || tree.tpe != CharType) baseResult else - genCallHelper("bC", baseResult) + genCallHelper(VarField.bC, baseResult) } private def transformApplyDynamicImport(tree: ApplyDynamicImport)( @@ -3012,7 +3012,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { } val innerCall = extractWithGlobals { - withDynamicGlobalVar("s", (className, method.name)) { v => + withDynamicGlobalVar(VarField.s, (className, method.name)) { v => js.Apply(v, newArgs) } } @@ -3232,7 +3232,7 @@ private[emitter] class FunctionEmitter(sjsGen: SJSGen) { keepOnlyDangerousVarNames = false) } - private def genApplyStaticLike(field: String, className: ClassName, + private def genApplyStaticLike(field: VarField, className: ClassName, method: MethodIdent, args: List[js.Tree])( implicit pos: Position): js.Tree = { js.Apply(globalVar(field, (className, method.name)), args) diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/PolyfillableBuiltin.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/PolyfillableBuiltin.scala index 743c9b437d..908d264a9f 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/PolyfillableBuiltin.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/PolyfillableBuiltin.scala @@ -15,7 +15,7 @@ package org.scalajs.linker.backend.emitter import org.scalajs.linker.interface.ESVersion private[emitter] sealed abstract class PolyfillableBuiltin( - val builtinName: String, val availableInESVersion: ESVersion) + val polyfillField: VarField, val availableInESVersion: ESVersion) private[emitter] object PolyfillableBuiltin { lazy val All: List[PolyfillableBuiltin] = List( @@ -27,18 +27,18 @@ private[emitter] object PolyfillableBuiltin { ) sealed abstract class GlobalVarBuiltin(val globalVar: String, - builtinName: String, availableInESVersion: ESVersion) - extends PolyfillableBuiltin(builtinName, availableInESVersion) + polyfillField: VarField, availableInESVersion: ESVersion) + extends PolyfillableBuiltin(polyfillField, availableInESVersion) sealed abstract class NamespacedBuiltin(val namespaceGlobalVar: String, - builtinName: String, availableInESVersion: ESVersion) - extends PolyfillableBuiltin(builtinName, availableInESVersion) + val builtinName: String, polyfillField: VarField, availableInESVersion: ESVersion) + extends PolyfillableBuiltin(polyfillField, availableInESVersion) - case object ObjectIsBuiltin extends NamespacedBuiltin("Object", "is", ESVersion.ES2015) - case object ImulBuiltin extends NamespacedBuiltin("Math", "imul", ESVersion.ES2015) - case object FroundBuiltin extends NamespacedBuiltin("Math", "fround", ESVersion.ES2015) + case object ObjectIsBuiltin extends NamespacedBuiltin("Object", "is", VarField.is, ESVersion.ES2015) + case object ImulBuiltin extends NamespacedBuiltin("Math", "imul", VarField.imul, ESVersion.ES2015) + case object FroundBuiltin extends NamespacedBuiltin("Math", "fround", VarField.fround, ESVersion.ES2015) case object PrivateSymbolBuiltin - extends GlobalVarBuiltin("Symbol", "privateJSFieldSymbol", ESVersion.ES2015) - case object GetOwnPropertyDescriptorsBuiltin - extends NamespacedBuiltin("Object", "getOwnPropertyDescriptors", ESVersion.ES2017) + extends GlobalVarBuiltin("Symbol", VarField.privateJSFieldSymbol, ESVersion.ES2015) + case object GetOwnPropertyDescriptorsBuiltin extends NamespacedBuiltin("Object", + "getOwnPropertyDescriptors", VarField.getOwnPropertyDescriptors, ESVersion.ES2017) } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/SJSGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/SJSGen.scala index e36ee63582..0449e0ed92 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/SJSGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/SJSGen.scala @@ -87,7 +87,7 @@ private[emitter] final class SJSGen( if (useBigIntForLongs) BigIntLiteral(0L) else - globalVar("L0", CoreVar) + globalVar(VarField.L0, CoreVar) } def genBoxedZeroOf(tpe: Type)( @@ -100,7 +100,7 @@ private[emitter] final class SJSGen( def genBoxedCharZero()( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { - globalVar("bC0", CoreVar) + globalVar(VarField.bC0, CoreVar) } def genLongModuleApply(methodName: MethodName, args: Tree*)( @@ -153,7 +153,7 @@ private[emitter] final class SJSGen( if (esFeatures.esVersion >= ESVersion.ES2015 && semantics.nullPointers == CheckedBehavior.Unchecked) Apply(args.head DOT "copyTo", args.tail) else - genCallHelper("systemArraycopy", args: _*) + genCallHelper(VarField.systemArraycopy, args: _*) } def genSelect(receiver: Tree, className: ClassName, field: irt.FieldIdent)( @@ -178,7 +178,7 @@ private[emitter] final class SJSGen( pos: Position): Tree = { val fieldName = { implicit val pos = field.pos - globalVar("r", (className, field.name)) + globalVar(VarField.r, (className, field.name)) } BracketSelect(receiver, fieldName) @@ -199,7 +199,7 @@ private[emitter] final class SJSGen( !globalKnowledge.isInterface(className)) { genIsInstanceOfClass(expr, className) } else { - Apply(globalVar("is", className), List(expr)) + Apply(globalVar(VarField.is, className), List(expr)) } case ArrayType(arrayTypeRef) => @@ -207,15 +207,15 @@ private[emitter] final class SJSGen( case ArrayTypeRef(_:PrimRef | ClassRef(ObjectClass), 1) => expr instanceof genArrayConstrOf(arrayTypeRef) case ArrayTypeRef(base, depth) => - Apply(typeRefVar("isArrayOf", base), List(expr, IntLiteral(depth))) + Apply(typeRefVar(VarField.isArrayOf, base), List(expr, IntLiteral(depth))) } case UndefType => expr === Undefined() case BooleanType => typeof(expr) === "boolean" - case CharType => expr instanceof globalVar("Char", CoreVar) - case ByteType => genCallHelper("isByte", expr) - case ShortType => genCallHelper("isShort", expr) - case IntType => genCallHelper("isInt", expr) + case CharType => expr instanceof globalVar(VarField.Char, CoreVar) + case ByteType => genCallHelper(VarField.isByte, expr) + case ShortType => genCallHelper(VarField.isShort, expr) + case IntType => genCallHelper(VarField.isInt, expr) case LongType => genIsLong(expr) case FloatType => genIsFloat(expr) case DoubleType => typeof(expr) === "number" @@ -239,7 +239,7 @@ private[emitter] final class SJSGen( */ BooleanLiteral(false) } else { - expr instanceof globalVar("c", className) + expr instanceof globalVar(VarField.c, className) } } @@ -251,10 +251,10 @@ private[emitter] final class SJSGen( className match { case BoxedUnitClass => expr === Undefined() case BoxedBooleanClass => typeof(expr) === "boolean" - case BoxedCharacterClass => expr instanceof globalVar("Char", CoreVar) - case BoxedByteClass => genCallHelper("isByte", expr) - case BoxedShortClass => genCallHelper("isShort", expr) - case BoxedIntegerClass => genCallHelper("isInt", expr) + case BoxedCharacterClass => expr instanceof globalVar(VarField.Char, CoreVar) + case BoxedByteClass => genCallHelper(VarField.isByte, expr) + case BoxedShortClass => genCallHelper(VarField.isShort, expr) + case BoxedIntegerClass => genCallHelper(VarField.isInt, expr) case BoxedLongClass => genIsLong(expr) case BoxedFloatClass => genIsFloat(expr) case BoxedDoubleClass => typeof(expr) === "number" @@ -267,8 +267,8 @@ private[emitter] final class SJSGen( pos: Position): Tree = { import TreeDSL._ - if (useBigIntForLongs) genCallHelper("isLong", expr) - else expr instanceof globalVar("c", LongImpl.RuntimeLongClass) + if (useBigIntForLongs) genCallHelper(VarField.isLong, expr) + else expr instanceof globalVar(VarField.c, LongImpl.RuntimeLongClass) } private def genIsFloat(expr: Tree)( @@ -276,7 +276,7 @@ private[emitter] final class SJSGen( pos: Position): Tree = { import TreeDSL._ - if (semantics.strictFloats) genCallHelper("isFloat", expr) + if (semantics.strictFloats) genCallHelper(VarField.isFloat, expr) else typeof(expr) === "number" } @@ -295,9 +295,9 @@ private[emitter] final class SJSGen( case UndefType => wg(Block(expr, Undefined())) case BooleanType => wg(!(!expr)) - case CharType => wg(genCallHelper("uC", expr)) + case CharType => wg(genCallHelper(VarField.uC, expr)) case ByteType | ShortType| IntType => wg(expr | 0) - case LongType => wg(genCallHelper("uJ", expr)) + case LongType => wg(genCallHelper(VarField.uJ, expr)) case DoubleType => wg(UnaryOp(irt.JSUnaryOp.+, expr)) case StringType => wg(expr || StringLiteral("")) @@ -313,21 +313,21 @@ private[emitter] final class SJSGen( case ClassType(ObjectClass) => expr case ClassType(className) => - Apply(globalVar("as", className), List(expr)) + Apply(globalVar(VarField.as, className), List(expr)) case ArrayType(ArrayTypeRef(base, depth)) => - Apply(typeRefVar("asArrayOf", base), List(expr, IntLiteral(depth))) - - case UndefType => genCallHelper("uV", expr) - case BooleanType => genCallHelper("uZ", expr) - case CharType => genCallHelper("uC", expr) - case ByteType => genCallHelper("uB", expr) - case ShortType => genCallHelper("uS", expr) - case IntType => genCallHelper("uI", expr) - case LongType => genCallHelper("uJ", expr) - case FloatType => genCallHelper("uF", expr) - case DoubleType => genCallHelper("uD", expr) - case StringType => genCallHelper("uT", expr) + Apply(typeRefVar(VarField.asArrayOf, base), List(expr, IntLiteral(depth))) + + case UndefType => genCallHelper(VarField.uV, expr) + case BooleanType => genCallHelper(VarField.uZ, expr) + case CharType => genCallHelper(VarField.uC, expr) + case ByteType => genCallHelper(VarField.uB, expr) + case ShortType => genCallHelper(VarField.uS, expr) + case IntType => genCallHelper(VarField.uI, expr) + case LongType => genCallHelper(VarField.uJ, expr) + case FloatType => genCallHelper(VarField.uF, expr) + case DoubleType => genCallHelper(VarField.uD, expr) + case StringType => genCallHelper(VarField.uT, expr) case AnyType => expr case NoType | NullType | NothingType | _:RecordType => @@ -386,7 +386,7 @@ private[emitter] final class SJSGen( BoxedFloatClass ) ::: nonSmallNumberHijackedClassesOrderedForTypeTests - def genCallHelper(helperName: String, args: Tree*)( + def genCallHelper(helperName: VarField, args: Tree*)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { Apply(globalVar(helperName, CoreVar), args.toList) @@ -405,7 +405,7 @@ private[emitter] final class SJSGen( Apply(genIdentBracketSelect(namespace, builtin.builtinName), args.toList) } } else { - WithGlobals(genCallHelper(builtin.builtinName, args: _*)) + WithGlobals(genCallHelper(builtin.polyfillField, args: _*)) } } @@ -413,18 +413,18 @@ private[emitter] final class SJSGen( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { import TreeDSL._ - Apply(globalVar("m", moduleClass), Nil) + Apply(globalVar(VarField.m, moduleClass), Nil) } def genScalaClassNew(className: ClassName, ctor: MethodName, args: Tree*)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { - val encodedClassVar = globalVar("c", className) + val encodedClassVar = globalVar(VarField.c, className) val argsList = args.toList if (globalKnowledge.hasInlineableInit(className)) { New(encodedClassVar, argsList) } else { - Apply(globalVar("ct", (className, ctor)), New(encodedClassVar, Nil) :: argsList) + Apply(globalVar(VarField.ct, (className, ctor)), New(encodedClassVar, Nil) :: argsList) } } @@ -456,7 +456,7 @@ private[emitter] final class SJSGen( def genNonNativeJSClassConstructor(className: ClassName)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { - Apply(globalVar("a", className), Nil) + Apply(globalVar(VarField.a, className), Nil) } def genLoadJSFromSpec(spec: irt.JSNativeLoadSpec, @@ -487,7 +487,7 @@ private[emitter] final class SJSGen( val moduleValue = VarRef(externalModuleFieldIdent(module)) path match { case "default" :: rest if moduleKind == ModuleKind.CommonJSModule => - val defaultField = genCallHelper("moduleDefault", moduleValue) + val defaultField = genCallHelper(VarField.moduleDefault, moduleValue) WithGlobals(pathSelection(defaultField, rest)) case _ => WithGlobals(pathSelection(moduleValue, path)) @@ -513,7 +513,7 @@ private[emitter] final class SJSGen( case length :: Nil => New(genArrayConstrOf(arrayTypeRef), length :: Nil) case _ => - genCallHelper("newArrayObject", genClassDataOf(arrayTypeRef), + genCallHelper(VarField.newArrayObject, genClassDataOf(arrayTypeRef), ArrayConstr(lengths)) } } @@ -551,9 +551,9 @@ private[emitter] final class SJSGen( arrayTypeRef match { case ArrayTypeRef(primRef: PrimRef, 1) => - globalVar("ac", primRef) + globalVar(VarField.ac, primRef) case ArrayTypeRef(ClassRef(ObjectClass), 1) => - globalVar("ac", ObjectClass) + globalVar(VarField.ac, ObjectClass) case _ => genClassDataOf(arrayTypeRef) DOT "constr" } @@ -576,7 +576,7 @@ private[emitter] final class SJSGen( pos: Position): Tree = { typeRef match { case typeRef: NonArrayTypeRef => - typeRefVar("d", typeRef) + typeRefVar(VarField.d, typeRef) case ArrayTypeRef(base, dims) => val baseData = genClassDataOf(base) @@ -598,6 +598,6 @@ private[emitter] final class SJSGen( if (semantics.nullPointers == CheckedBehavior.Unchecked) obj else - genCallHelper("n", obj) + genCallHelper(VarField.n, obj) } } diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarField.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarField.scala new file mode 100644 index 0000000000..2be691d96e --- /dev/null +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarField.scala @@ -0,0 +1,277 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.linker.backend.emitter + +/** Namespace for generated fields. + * + * Mainly to avoid duplicate strings in memory. + * + * Also gives us additional compile-time safety against typos. + */ +private[emitter] final class VarField private (val str: String) extends AnyVal + +private[emitter] object VarField { + private def mk(str: String): VarField = { + require(str(0) == '$') + new VarField(str) + } + + // Scala class related fields. + + /** Scala classes (constructor functions). */ + final val c = mk("$c") + + /** Inheritable constructor functions for Scala classes. */ + final val h = mk("$h") + + /** Scala class constructors (). */ + final val ct = mk("$ct") + + /** Scala class initializers (). */ + final val sct = mk("$sct") + + /** Private (instance) methods. */ + final val p = mk("$p") + + /** Public static methods. */ + final val s = mk("$s") + + /** Private static methods. */ + final val ps = mk("$ps") + + /** Interface default and hijacked public methods. */ + final val f = mk("$f") + + /** Static fields. */ + final val t = mk("$t") + + /** Scala module accessor. */ + final val m = mk("$m") + + /** Var / let to store Scala module instance. + * + * Also used for null check in CoreJSLib. + */ + final val n = mk("$n") + + // JS class related fields. + + /** JS Class acessor / factories. */ + final val a = mk("$a") + + /** Var / let to store (top-level) JS Class. */ + final val b = mk("$b") + + /** Names for private JS fields. */ + final val r = mk("$r") + + // Reflection + + /** Class data. */ + final val d = mk("$d") + + /** isInstanceOf functions. + * + * Also used as Object.is polyfill. + */ + final val is = mk("$is") + + /** asInstanceOf functions. */ + final val as = mk("$as") + + /** isInstanceOf for array functions. */ + final val isArrayOf = mk("$isArrayOf") + + /** asInstanceOf for array functions. */ + final val asArrayOf = mk("$asArrayOf") + + // Modules + + /** External ES module imports. */ + final val i = mk("$i") + + /** Internal ES module imports. */ + final val j = mk("$j") + + /** ES module const export names. */ + final val e = mk("$e") + + /** Setters for globally mutable vars (for ES Modules). */ + final val u = mk("$u") + + // Local fields: Used to generate non-clashing *local* identifiers. + + /** Synthetic vars for the FunctionEmitter. */ + final val x = mk("$x") + + /** Dummy inheritable constructors for JS classes. */ + final val hh = mk("$hh") + + /** Local field for class captures. */ + final val cc = mk("$cc") + + /** Local field for super class. */ + final val superClass = mk("$superClass") + + /** Local field for this replacement. */ + final val thiz = mk("$thiz") + + /** Local field for dynamic imports. */ + final val module = mk("$module") + + // Core fields: Generated by the CoreJSLib + + /** The linking info object. */ + final val linkingInfo = mk("$linkingInfo") + + /** The TypeData class. */ + final val TypeData = mk("$TypeData") + + /** Long zero. */ + final val L0 = mk("$L0") + + /** Dispatchers. */ + final val dp = mk("$dp") + + // Char + + /** The Char class. */ + final val Char = mk("$Char") + + /** Boxed Char zero. */ + final val bC0 = mk("$bC0") + + /** Box char. */ + final val bC = mk("$bC") + + final val charAt = mk("$charAt") + + // Object helpers + + final val objectClone = mk("$objectClone") + + final val objectOrArrayClone = mk("$objectOrArrayClone") + + final val objectGetClass = mk("$objectGetClass") + + final val objectClassName = mk("$objectClassName") + + final val throwNullPointerException = mk("$throwNullPointerException") + + final val throwModuleInitError = mk("$throwModuleInitError") + + final val valueDescription = mk("$valueDescription") + + final val propertyName = mk("$propertyName") + + // ID hash subsystem + + final val systemIdentityHashCode = mk("$systemIdentityHashCode") + + final val lastIDHash = mk("$lastIDHash") + + final val idHashCodeMap = mk("$idHashCodeMap") + + // Cast helpers + + final val isByte = mk("$isByte") + + final val isShort = mk("$isShort") + + final val isInt = mk("$isInt") + + final val isLong = mk("$isLong") + + final val isFloat = mk("$isFloat") + + final val throwClassCastException = mk("$throwClassCastException") + + final val noIsInstance = mk("$noIsInstance") + + // Unboxes + final val uV = mk("$uV") + final val uZ = mk("$uZ") + final val uC = mk("$uC") + final val uB = mk("$uB") + final val uS = mk("$uS") + final val uI = mk("$uI") + final val uJ = mk("$uJ") + final val uF = mk("$uF") + final val uD = mk("$uD") + final val uT = mk("$uT") + + // Arrays + + /** Array constructors. */ + final val ac = mk("$ac") + + /** Inheritable array constructors. */ + final val ah = mk("$ah") + + final val arraycopyGeneric = mk("$arraycopyGeneric") + + final val arraycopyCheckBounds = mk("$arraycopyCheckBounds") + + final val systemArraycopy = mk("$systemArraycopy") + + final val systemArraycopyRefs = mk("$systemArraycopyRefs") + + final val systemArraycopyFull = mk("$systemArraycopyFull") + + final val newArrayObject = mk("$newArrayObject") + + final val newArrayObjectInternal = mk("$newArrayObjectInternal") + + final val throwArrayCastException = mk("$throwArrayCastException") + + final val throwArrayIndexOutOfBoundsException = mk("$throwArrayIndexOutOFBoundsException") + + final val throwArrayStoreException = mk("$throwArrayStoreException") + + final val throwNegativeArraySizeException = mk("$throwNegativeArraySizeException") + + // JS helpers + + final val newJSObjectWithVarargs = mk("$newJSObjectWithVarargs") + + final val superGet = mk("$superGet") + + final val superSet = mk("$superSet") + + final val resolveSuperRef = mk("$resolveSuperRef") + + final val moduleDefault = mk("$moduleDefault") + + // Arithmetic Call Helpers + + final val intDiv = mk("$intDiv") + + final val intMod = mk("$intMod") + + final val longToFloat = mk("$longToFloat") + + final val longDiv = mk("$longDiv") + + final val longMod = mk("$longMod") + + final val doubleToLong = mk("$doubleToLong") + + final val doubleToInt = mk("$doubleToInt") + + // Polyfills + + final val imul = mk("$imul") + final val fround = mk("$fround") + final val privateJSFieldSymbol = mk("$privateJSFieldSymbol") + final val getOwnPropertyDescriptors = mk("$getOwnPropertyDescriptors") +} diff --git a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarGen.scala b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarGen.scala index cff6305663..b58ac77235 100644 --- a/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarGen.scala +++ b/linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/VarGen.scala @@ -39,7 +39,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, import jsGen._ import nameGen._ - def globalVar[T: Scope](field: String, scope: T, + def globalVar[T: Scope](field: VarField, scope: T, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { @@ -51,7 +51,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, } } - def globalClassDef[T: Scope](field: String, scope: T, + def globalClassDef[T: Scope](field: VarField, scope: T, parentClass: Option[Tree], members: List[Tree], origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, pos: Position): WithGlobals[List[Tree]] = { @@ -59,7 +59,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, maybeExport(ident, ClassDef(Some(ident), parentClass, members), mutable = false) } - def globalFunctionDef[T: Scope](field: String, scope: T, + def globalFunctionDef[T: Scope](field: VarField, scope: T, args: List[ParamDef], restParam: Option[ParamDef], body: Tree, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, pos: Position): WithGlobals[List[Tree]] = { @@ -67,7 +67,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, maybeExport(ident, FunctionDef(ident, args, restParam, body), mutable = false) } - def globalVarDef[T: Scope](field: String, scope: T, value: Tree, + def globalVarDef[T: Scope](field: VarField, scope: T, value: Tree, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, pos: Position): WithGlobals[List[Tree]] = { val ident = globalVarIdent(field, scope, origName) @@ -75,7 +75,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, } /** Attention: A globalVarDecl may only be modified from the module it was declared in. */ - def globalVarDecl[T: Scope](field: String, scope: T, + def globalVarDecl[T: Scope](field: VarField, scope: T, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, pos: Position): WithGlobals[List[Tree]] = { val ident = globalVarIdent(field, scope, origName) @@ -86,7 +86,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, * module. As such, an additional field needs to be provided for an * additional setter. This is used when generating ES modules. */ - def globallyMutableVarDef[T: Scope](field: String, setterField: String, + def globallyMutableVarDef[T: Scope](field: VarField, setterField: VarField, scope: T, value: Tree, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, pos: Position): WithGlobals[List[Tree]] = { val ident = globalVarIdent(field, scope, origName) @@ -116,7 +116,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, globalKnowledge.getModule(scopeType.reprClass(scope)) != moduleContext.moduleID } - def globalVarExport[T: Scope](field: String, scope: T, exportName: ExportName, + def globalVarExport[T: Scope](field: VarField, scope: T, exportName: ExportName, origName: OriginalName = NoOriginalName)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { @@ -133,12 +133,12 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, } /** Apply the provided body to a dynamically loaded global var */ - def withDynamicGlobalVar[T: Scope](field: String, scope: T)(body: Tree => Tree)( + def withDynamicGlobalVar[T: Scope](field: VarField, scope: T)(body: Tree => Tree)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[Tree] = { val ident = globalVarIdent(field, scope) - val module = fileLevelVarIdent("$module") + val module = fileLevelVarIdent(VarField.module) def unitPromise = { globalRef("Promise").map { promise => @@ -186,7 +186,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, } } - private def globalVarIdent[T](field: String, scope: T, + private def globalVarIdent[T](field: VarField, scope: T, origName: OriginalName = NoOriginalName)( implicit pos: Position, scopeType: Scope[T]): Ident = { genericIdent(field, scopeType.subField(scope), origName) @@ -205,7 +205,7 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, * * Returns the relevant coreJSLibVar for primitive types, globalVar otherwise. */ - def typeRefVar(field: String, typeRef: NonArrayTypeRef)( + def typeRefVar(field: VarField, typeRef: NonArrayTypeRef)( implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge, pos: Position): Tree = { /* Explicitly bringing `PrimRefScope` and `ClassScope` as local implicit @@ -229,41 +229,41 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, } } - def fileLevelVar(field: String, subField: String, + def fileLevelVar(field: VarField, subField: String, origName: OriginalName = NoOriginalName)( implicit pos: Position): VarRef = { VarRef(fileLevelVarIdent(field, subField, origName)) } - def fileLevelVar(field: String)(implicit pos: Position): VarRef = + def fileLevelVar(field: VarField)(implicit pos: Position): VarRef = VarRef(fileLevelVarIdent(field)) - def fileLevelVarIdent(field: String, subField: String, + def fileLevelVarIdent(field: VarField, subField: String, origName: OriginalName = NoOriginalName)( implicit pos: Position): Ident = { genericIdent(field, subField, origName) } - def fileLevelVarIdent(field: String)(implicit pos: Position): Ident = + def fileLevelVarIdent(field: VarField)(implicit pos: Position): Ident = fileLevelVarIdent(field, NoOriginalName) - def fileLevelVarIdent(field: String, origName: OriginalName)( + def fileLevelVarIdent(field: VarField, origName: OriginalName)( implicit pos: Position): Ident = { genericIdent(field, "", origName) } def externalModuleFieldIdent(moduleName: String)(implicit pos: Position): Ident = - fileLevelVarIdent("i", genModuleName(moduleName), OriginalName(moduleName)) + fileLevelVarIdent(VarField.i, genModuleName(moduleName), OriginalName(moduleName)) def internalModuleFieldIdent(module: ModuleID)(implicit pos: Position): Ident = - fileLevelVarIdent("j", genModuleName(module.id), OriginalName(module.id)) + fileLevelVarIdent(VarField.j, genModuleName(module.id), OriginalName(module.id)) - private def genericIdent(field: String, subField: String, + private def genericIdent(field: VarField, subField: String, origName: OriginalName = NoOriginalName)( implicit pos: Position): Ident = { val name = - if (subField == "") "$" + field - else "$" + field + "_" + subField + if (subField == "") field.str + else field.str + "_" + subField Ident(avoidClashWithGlobalRef(name), origName) } @@ -358,6 +358,11 @@ private[emitter] final class VarGen(jsGen: JSGen, nameGen: NameGen, def reprClass(x: (ClassName, MethodName)): ClassName = x._1 } + implicit object DispatcherScope extends Scope[MethodName] { + def subField(x: MethodName): String = genName(x) + def reprClass(x: MethodName): ClassName = ObjectClass + } + implicit object CoreJSLibScope extends Scope[CoreVar.type] { def subField(x: CoreVar.type): String = "" def reprClass(x: CoreVar.type): ClassName = ObjectClass