@@ -130,7 +130,6 @@ private[emitter] object CoreJSLib {
130
130
defineLinkingInfo() :::
131
131
defineJSBuiltinsSnapshotsAndPolyfills() :::
132
132
declareCachedL0() :::
133
- definePropertyName() :::
134
133
defineCharClass() :::
135
134
defineRuntimeFunctions() :::
136
135
defineObjectGetClassFunctions() :::
@@ -526,23 +525,6 @@ private[emitter] object CoreJSLib {
526
525
))
527
526
}
528
527
529
- private def definePropertyName (): List [Tree ] = {
530
- /* Encodes a property name for runtime manipulation.
531
- *
532
- * Usage:
533
- * env.propertyName({someProp:0})
534
- * Returns:
535
- * "someProp"
536
- * Useful when the property is renamed by a global optimizer (like
537
- * Closure) but we must still get hold of a string of that name for
538
- * runtime reflection.
539
- */
540
- defineFunction1(VarField .propertyName) { obj =>
541
- val prop = varRef(" prop" )
542
- ForIn (genEmptyImmutableLet(prop.ident), obj, Return (prop))
543
- }
544
- }
545
-
546
528
private def defineCharClass (): List [Tree ] = {
547
529
val ctor = {
548
530
val c = varRef(" c" )
@@ -562,6 +544,7 @@ private[emitter] object CoreJSLib {
562
544
extractWithGlobals(globalClassDef(VarField .Char , CoreVar , None , ctor :: toStr :: Nil ))
563
545
} else {
564
546
defineFunction(VarField .Char , ctor.args, ctor.body) :::
547
+ setPrototypeVar(globalVar(VarField .Char , CoreVar )) :::
565
548
assignES5ClassMembers(globalVar(VarField .Char , CoreVar ), List (toStr))
566
549
}
567
550
}
@@ -1528,16 +1511,16 @@ private[emitter] object CoreJSLib {
1528
1511
val clsDef = {
1529
1512
extractWithGlobals(globalFunctionDef(VarField .ac, componentTypeRef,
1530
1513
ctor.args, ctor.restParam, ctor.body)) :::
1531
- (ArrayClass .prototype := New (globalVar(VarField .h, ObjectClass ), Nil )) ::
1532
- (ArrayClass .prototype DOT " constructor" := ArrayClass ) ::
1514
+ genAssignPrototype (ArrayClass , New (globalVar(VarField .h, ObjectClass ), Nil )) ::
1515
+ (prototypeFor( ArrayClass ) DOT " constructor" := ArrayClass ) ::
1533
1516
assignES5ClassMembers(ArrayClass , members)
1534
1517
}
1535
1518
1536
1519
componentTypeRef match {
1537
1520
case _ : ClassRef =>
1538
1521
clsDef :::
1539
1522
extractWithGlobals(globalFunctionDef(VarField .ah, ObjectClass , Nil , None , Skip ())) :::
1540
- (globalVar(VarField .ah, ObjectClass ).prototype := ArrayClass .prototype ) :: Nil
1523
+ (globalVar(VarField .ah, ObjectClass ).prototype := prototypeFor( ArrayClass ) ) :: Nil
1541
1524
case _ : PrimRef =>
1542
1525
clsDef
1543
1526
}
@@ -1651,23 +1634,34 @@ private[emitter] object CoreJSLib {
1651
1634
}
1652
1635
1653
1636
val initClass = {
1654
- val internalNameObj = varRef(" internalNameObj" )
1655
- val isInterface = varRef(" isInterface" )
1637
+ /* This is either:
1638
+ * - an int: 1 means isInterface; 2 means isJSType; 0 otherwise
1639
+ * - a Scala class constructor: means 0 + assign `kindOrCtor.prototype.$classData = this;`
1640
+ */
1641
+ val kindOrCtor = varRef(" kindOrCtor" )
1642
+
1643
+ val hasParentData = globalKnowledge.isParentDataAccessed
1644
+
1656
1645
val fullName = varRef(" fullName" )
1657
1646
val ancestors = varRef(" ancestors" )
1658
- val isJSType = varRef(" isJSType" )
1659
1647
val parentData = varRef(" parentData" )
1660
1648
val isInstance = varRef(" isInstance" )
1661
1649
val internalName = varRef(" internalName" )
1662
1650
val that = varRef(" that" )
1663
1651
val depth = varRef(" depth" )
1664
1652
val obj = varRef(" obj" )
1665
- MethodDef (static = false , Ident (cpn.initClass),
1666
- paramList(internalNameObj, isInterface, fullName, ancestors,
1667
- isJSType, parentData, isInstance), None , {
1653
+ val params =
1654
+ if (hasParentData) paramList(kindOrCtor, fullName, ancestors, parentData, isInstance)
1655
+ else paramList(kindOrCtor, fullName, ancestors, isInstance)
1656
+ MethodDef (static = false , Ident (cpn.initClass), params, None , {
1668
1657
Block (
1669
- const(internalName, genCallHelper(VarField .propertyName, internalNameObj)),
1670
- if (globalKnowledge.isParentDataAccessed)
1658
+ /* Extract the internalName, which is the first property of ancestors.
1659
+ * We use `getOwnPropertyNames()`, which since ES 2015 guarantees
1660
+ * to return non-integer string keys in creation order.
1661
+ */
1662
+ const(internalName,
1663
+ BracketSelect (Apply (genIdentBracketSelect(ObjectRef , " getOwnPropertyNames" ), List (ancestors)), 0 )),
1664
+ if (hasParentData)
1671
1665
privateFieldSet(cpn.parentData, parentData)
1672
1666
else
1673
1667
Skip (),
@@ -1678,15 +1672,18 @@ private[emitter] object CoreJSLib {
1678
1672
Return (! (! (BracketSelect (that DOT cpn.ancestors, internalName))))
1679
1673
})
1680
1674
}),
1681
- privateFieldSet(cpn.isJSType, ! ( ! isJSType) ),
1675
+ privateFieldSet(cpn.isJSType, kindOrCtor === 2 ),
1682
1676
publicFieldSet(cpn.name, fullName),
1683
- publicFieldSet(cpn.isInterface, isInterface ),
1677
+ publicFieldSet(cpn.isInterface, kindOrCtor === 1 ),
1684
1678
publicFieldSet(cpn.isInstance, isInstance || {
1685
1679
genArrowFunction(paramList(obj), {
1686
1680
Return (! (! (obj && (obj DOT classData) &&
1687
1681
BracketSelect (obj DOT classData DOT cpn.ancestors, internalName))))
1688
1682
})
1689
1683
}),
1684
+ If (typeof(kindOrCtor) !== str(" number" ), {
1685
+ kindOrCtor.prototype DOT cpn.classData := This ()
1686
+ }),
1690
1687
Return (This ())
1691
1688
)
1692
1689
})
@@ -1697,7 +1694,6 @@ private[emitter] object CoreJSLib {
1697
1694
val name = varRef(" name" )
1698
1695
1699
1696
Block (
1700
- arrayClass.prototype DOT classData := This (),
1701
1697
const(name, str(" [" ) + (componentData DOT cpn.arrayEncodedName)),
1702
1698
privateFieldSet(cpn.constr, arrayClass),
1703
1699
if (globalKnowledge.isParentDataAccessed)
@@ -1729,6 +1725,7 @@ private[emitter] object CoreJSLib {
1729
1725
MethodDef (static = false , Ident (cpn.initSpecializedArray),
1730
1726
paramList(componentData, arrayClass, typedArrayClass, isAssignableFromFun), None , {
1731
1727
Block (
1728
+ arrayClass.prototype DOT classData := This (),
1732
1729
initArrayCommonBody(arrayClass, componentData, componentData, 1 ),
1733
1730
const(self, This ()), // capture `this` for use in arrow fun
1734
1731
privateFieldSet(cpn.isAssignableFromFun, isAssignableFromFun || {
@@ -1833,14 +1830,19 @@ private[emitter] object CoreJSLib {
1833
1830
val members = set ::: copyTo ::: clone :: Nil
1834
1831
1835
1832
if (useClassesForRegularClasses) {
1836
- ClassDef (Some (ArrayClass .ident), Some (globalVar(VarField .ac, ObjectClass )),
1837
- ctor :: members)
1833
+ Block (
1834
+ ClassDef (Some (ArrayClass .ident), Some (globalVar(VarField .ac, ObjectClass )),
1835
+ ctor :: members),
1836
+ ArrayClass .prototype DOT cpn.classData := This ()
1837
+ )
1838
1838
} else {
1839
1839
Block (
1840
1840
FunctionDef (ArrayClass .ident, ctor.args, ctor.restParam, ctor.body) ::
1841
- (ArrayClass .prototype := New (globalVar(VarField .ah, ObjectClass ), Nil )) ::
1842
- (ArrayClass .prototype DOT " constructor" := ArrayClass ) ::
1843
- assignES5ClassMembers(ArrayClass , members)
1841
+ genAssignPrototype(ArrayClass , New (globalVar(VarField .ah, ObjectClass ), Nil ), localDecl = true ) ::
1842
+ (prototypeFor(ArrayClass ) DOT " constructor" := ArrayClass ) ::
1843
+ assignES5ClassMembers(ArrayClass , members) :::
1844
+ (prototypeFor(ArrayClass ) DOT cpn.classData := This ()) ::
1845
+ Nil
1844
1846
)
1845
1847
}
1846
1848
}
@@ -2000,6 +2002,7 @@ private[emitter] object CoreJSLib {
2000
2002
extractWithGlobals(globalClassDef(VarField .TypeData , CoreVar , None , ctor :: members))
2001
2003
} else {
2002
2004
defineFunction(VarField .TypeData , ctor.args, ctor.body) :::
2005
+ setPrototypeVar(globalVar(VarField .TypeData , CoreVar )) :::
2003
2006
assignES5ClassMembers(globalVar(VarField .TypeData , CoreVar ), members)
2004
2007
}
2005
2008
}
@@ -2159,7 +2162,7 @@ private[emitter] object CoreJSLib {
2159
2162
for {
2160
2163
MethodDef (static, name, args, restParam, body) <- members
2161
2164
} yield {
2162
- val target = if (static) classRef else classRef.prototype
2165
+ val target = if (static) classRef else prototypeFor( classRef)
2163
2166
genPropSelect(target, name) := Function (arrow = false , args, restParam, body)
2164
2167
}
2165
2168
}
0 commit comments