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
|
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
}
class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) {
import JSPrimitives._
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
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)
primitives.toMap
}
}
|