1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
package dotty.tools.backend.sjs
import dotty.tools.dotc.core._
import Names.TermName
import StdNames._
import Types._
import Contexts._
import Symbols._
import dotty.tools.dotc.ast.tpd._
import dotty.tools.dotc.backend.jvm.DottyPrimitives
import scala.collection.mutable
object JSPrimitives {
final val GETCLASS = 301 // jl.Object.getClass()
final val F2JS = 302 // js.Any.fromFunctionN
final val F2JSTHIS = 303 // js.ThisFunction.fromFunctionN
final val DYNNEW = 304 // js.Dynamic.newInstance
final val DYNLIT = 305 // js.Dynamic.literal.applyDynamic{,Named}
final val DICT_DEL = 306 // js.Dictionary.delete
final val ARR_CREATE = 307 // js.Array.apply (array literal syntax)
final val TYPEOF = 308 // js.typeOf(x)
final val DEBUGGER = 309 // js.debugger()
final val HASPROP = 310 // js.Object.hasProperty(o, p), equiv to `p in o` in JS
final val OBJPROPS = 311 // js.Object.properties(o), equiv to `for (p in o)` in JS
final val JS_NATIVE = 312 // js.native. Marker method. Fails if tried to be emitted.
final val UNITVAL = 313 // () value, which is undefined
final val UNITTYPE = 314 // BoxedUnit.TYPE (== classOf[Unit])
final val CONSTRUCTOROF = 315 // runtime.constructorOf(clazz)
final val ENV_INFO = 316 // runtime.environmentInfo
final val LINKING_INFO = 317 // runtime.linkingInfo
final val THROW = 318 // <special-ops>.throw
}
class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) {
import JSPrimitives._
import scala.tools.nsc.backend.ScalaPrimitives._
private lazy val jsPrimitives: Map[Symbol, Int] = initJSPrimitives(ctx)
override def getPrimitive(sym: Symbol): Int =
jsPrimitives.getOrElse(sym, super.getPrimitive(sym))
override def getPrimitive(app: Apply, tpe: Type)(implicit ctx: Context): Int =
jsPrimitives.getOrElse(app.fun.symbol, super.getPrimitive(app, tpe))
override def isPrimitive(fun: Tree): Boolean =
jsPrimitives.contains(fun.symbol(ctx)) || super.isPrimitive(fun)
/** Initialize the primitive map */
private def initJSPrimitives(implicit ctx: Context): Map[Symbol, Int] = {
val primitives = new mutable.HashMap[Symbol, Int]()
// !!! Code duplicate with DottyPrimitives
/** Add a primitive operation to the map */
def addPrimitive(s: Symbol, code: Int): Unit = {
assert(!(primitives contains s), "Duplicate primitive " + s)
primitives(s) = code
}
def addPrimitives(cls: Symbol, method: TermName, code: Int)(implicit ctx: Context): Unit = {
val alts = cls.info.member(method).alternatives.map(_.symbol)
if (alts.isEmpty) {
ctx.error(s"Unknown primitive method $cls.$method")
} else {
for (s <- alts)
addPrimitive(s, code)
}
}
val jsdefn = JSDefinitions.jsdefn
// For some reason, the JVM primitive set does not register those
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newBooleanArray")), NEW_ZARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newByteArray")), NEW_BARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newShortArray")), NEW_SARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newCharArray")), NEW_CARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newIntArray")), NEW_IARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newLongArray")), NEW_LARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newFloatArray")), NEW_FARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newDoubleArray")), NEW_DARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newRefArray")), NEW_OARRAY)
addPrimitive(defn.DottyArraysModule.requiredMethod(Names.termName("newUnitArray")), NEW_OARRAY)
addPrimitive(defn.Any_getClass, GETCLASS)
for (i <- 0 to 22)
addPrimitive(jsdefn.JSAny_fromFunction(i), F2JS)
for (i <- 1 to 22)
addPrimitive(jsdefn.JSThisFunction_fromFunction(i), F2JSTHIS)
addPrimitive(jsdefn.JSDynamic_newInstance, DYNNEW)
addPrimitive(jsdefn.JSDynamicLiteral_applyDynamicNamed, DYNLIT)
addPrimitive(jsdefn.JSDynamicLiteral_applyDynamic, DYNLIT)
addPrimitive(jsdefn.JSDictionary_delete, DICT_DEL)
//addPrimitive(jsdefn.JSArray_create, ARR_CREATE)
addPrimitive(jsdefn.JSPackage_typeOf, TYPEOF)
addPrimitive(jsdefn.JSPackage_debugger, DEBUGGER)
addPrimitive(jsdefn.JSPackage_native, JS_NATIVE)
addPrimitive(jsdefn.JSObject_hasProperty, HASPROP)
addPrimitive(jsdefn.JSObject_properties, OBJPROPS)
addPrimitive(defn.BoxedUnit_UNIT, UNITVAL)
//addPrimitive(defn.BoxedUnit_TYPE, UNITTYPE)
//addPrimitive(jsdefn.Runtime_constructorOf, CONSTRUCTOROF)
//addPrimitive(jsdefn.Runtime_environmentInfo, ENV_INFO)
//addPrimitive(jsdefn.Runtime_linkingInfo, LINKING_INFO)
addPrimitive(defn.throwMethod, THROW)
primitives.toMap
}
}
|