@@ -100,7 +100,7 @@ public let CodeGenerators: [CodeGenerator] = [
100
100
101
101
ValueGenerator ( " BuiltinObjectInstanceGenerator " ) { b, n in
102
102
let builtin = chooseUniform ( from: [ " Array " , " Map " , " WeakMap " , " Set " , " WeakSet " , " Date " ] )
103
- let constructor = b. loadBuiltin ( builtin)
103
+ let constructor = b. createNamedVariable ( forBuiltin : builtin)
104
104
if builtin == " Array " {
105
105
let size = b. loadInt ( b. randomSize ( upTo: 0x1000 ) )
106
106
b. construct ( constructor, withArgs: [ size] )
@@ -113,8 +113,8 @@ public let CodeGenerators: [CodeGenerator] = [
113
113
ValueGenerator ( " TypedArrayGenerator " ) { b, n in
114
114
for _ in 0 ..< n {
115
115
let size = b. loadInt ( b. randomSize ( upTo: 0x1000 ) )
116
- let constructor = b. loadBuiltin (
117
- chooseUniform (
116
+ let constructor = b. createNamedVariable (
117
+ forBuiltin : chooseUniform (
118
118
from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " ]
119
119
)
120
120
)
@@ -277,7 +277,7 @@ public let CodeGenerators: [CodeGenerator] = [
277
277
278
278
CodeGenerator ( " DisposableVariableGenerator " , inContext: . subroutine, inputs: . one) { b, val in
279
279
assert ( b. context. contains ( . subroutine) )
280
- let dispose = b. getProperty ( " dispose " , of: b. loadBuiltin ( " Symbol " ) ) ;
280
+ let dispose = b. getProperty ( " dispose " , of: b. createNamedVariable ( forBuiltin : " Symbol " ) ) ;
281
281
let disposableVariable = b. buildObjectLiteral { obj in
282
282
obj. addProperty ( " value " , as: val)
283
283
obj. addComputedMethod ( dispose, with: . parameters( n: 0 ) ) { args in
@@ -289,7 +289,7 @@ public let CodeGenerators: [CodeGenerator] = [
289
289
290
290
CodeGenerator ( " AsyncDisposableVariableGenerator " , inContext: . asyncFunction, inputs: . one) { b, val in
291
291
assert ( b. context. contains ( . asyncFunction) )
292
- let asyncDispose = b. getProperty ( " asyncDispose " , of: b. loadBuiltin ( " Symbol " ) )
292
+ let asyncDispose = b. getProperty ( " asyncDispose " , of: b. createNamedVariable ( forBuiltin : " Symbol " ) )
293
293
let asyncDisposableVariable = b. buildObjectLiteral { obj in
294
294
obj. addProperty ( " value " , as: val)
295
295
obj. addComputedMethod ( asyncDispose, with: . parameters( n: 0 ) ) { args in
@@ -770,11 +770,26 @@ public let CodeGenerators: [CodeGenerator] = [
770
770
771
771
// We don't treat this as a ValueGenerator since it doesn't create a new value, it only accesses an existing one.
772
772
CodeGenerator ( " BuiltinGenerator " ) { b in
773
- b. loadBuiltin ( b. randomBuiltin ( ) )
773
+ b. createNamedVariable ( forBuiltin: b. randomBuiltin ( ) )
774
+ } ,
775
+
776
+ CodeGenerator ( " NamedVariableGenerator " ) { b in
777
+ // We're using the custom property names set from the environment for named variables.
778
+ // It's not clear if there's something better since that set should be relatively small
779
+ // (increasing the probability that named variables will be reused), and it also makes
780
+ // sense to use property names if we're inside a `with` statement.
781
+ let name = b. randomCustomPropertyName ( )
782
+ let declarationMode = chooseUniform ( from: NamedVariableDeclarationMode . allCases)
783
+ if declarationMode != . none {
784
+ b. createNamedVariable ( name, declarationMode: declarationMode, initialValue: b. randomVariable ( ) )
785
+ } else {
786
+ b. createNamedVariable ( name, declarationMode: declarationMode)
787
+ }
774
788
} ,
775
789
776
790
CodeGenerator ( " BuiltinOverwriteGenerator " , inputs: . one) { b, value in
777
- b. storeNamedVariable ( b. randomBuiltin ( ) , value)
791
+ let builtin = b. createNamedVariable ( b. randomBuiltin ( ) , declarationMode: . none)
792
+ b. reassign ( builtin, to: value)
778
793
} ,
779
794
780
795
RecursiveCodeGenerator ( " PlainFunctionGenerator " ) { b in
@@ -1477,7 +1492,7 @@ public let CodeGenerators: [CodeGenerator] = [
1477
1492
//
1478
1493
1479
1494
CodeGenerator ( " WellKnownPropertyLoadGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
1480
- let Symbol = b. loadBuiltin ( " Symbol " )
1495
+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
1481
1496
// The Symbol constructor is just a "side effect" of this generator and probably shouldn't be used by following generators.
1482
1497
b. hide ( Symbol)
1483
1498
let name = chooseUniform ( from: JavaScriptEnvironment . wellKnownSymbols)
@@ -1486,7 +1501,7 @@ public let CodeGenerators: [CodeGenerator] = [
1486
1501
} ,
1487
1502
1488
1503
CodeGenerator ( " WellKnownPropertyStoreGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
1489
- let Symbol = b. loadBuiltin ( " Symbol " )
1504
+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
1490
1505
b. hide ( Symbol)
1491
1506
let name = chooseUniform ( from: JavaScriptEnvironment . wellKnownSymbols)
1492
1507
let propertyName = b. getProperty ( name, of: Symbol)
@@ -1511,13 +1526,13 @@ public let CodeGenerators: [CodeGenerator] = [
1511
1526
CodeGenerator ( " MethodCallWithDifferentThisGenerator " , inputs: . preferred( . object( ) , . object( ) ) ) { b, obj, this in
1512
1527
guard let methodName = b. type ( of: obj) . randomMethod ( ) else { return }
1513
1528
let arguments = b. randomArguments ( forCallingMethod: methodName, on: obj)
1514
- let Reflect = b. loadBuiltin ( " Reflect " )
1529
+ let Reflect = b. createNamedVariable ( forBuiltin : " Reflect " )
1515
1530
let args = b. createArray ( with: arguments)
1516
1531
b. callMethod ( " apply " , on: Reflect, withArgs: [ b. getProperty ( methodName, of: obj) , this, args] )
1517
1532
} ,
1518
1533
1519
1534
CodeGenerator ( " ConstructWithDifferentNewTargetGenerator " , inputs: . preferred( . constructor( ) , . constructor( ) ) ) { b, newTarget, constructor in
1520
- let reflect = b. loadBuiltin ( " Reflect " )
1535
+ let reflect = b. createNamedVariable ( forBuiltin : " Reflect " )
1521
1536
let arguments = [ constructor, b. createArray ( with: b. randomArguments ( forCalling: constructor) ) , newTarget]
1522
1537
b. callMethod ( " construct " , on: reflect, withArgs: arguments)
1523
1538
} ,
@@ -1543,7 +1558,7 @@ public let CodeGenerators: [CodeGenerator] = [
1543
1558
}
1544
1559
let handler = b. createObject ( with: handlerProperties)
1545
1560
1546
- let Proxy = b. loadBuiltin ( " Proxy " )
1561
+ let Proxy = b. createNamedVariable ( forBuiltin : " Proxy " )
1547
1562
b. hide ( Proxy) // We want the proxy to be used by following code generators, not the Proxy constructor
1548
1563
b. construct ( Proxy, withArgs: [ target, handler] )
1549
1564
} ,
@@ -1553,7 +1568,7 @@ public let CodeGenerators: [CodeGenerator] = [
1553
1568
// TODO could provide type hints here for the parameters.
1554
1569
b. buildRecursive ( )
1555
1570
}
1556
- let Promise = b. loadBuiltin ( " Promise " )
1571
+ let Promise = b. createNamedVariable ( forBuiltin : " Promise " )
1557
1572
b. hide ( Promise) // We want the promise to be used by following code generators, not the Promise constructor
1558
1573
b. construct ( Promise, withArgs: [ handler] )
1559
1574
} ,
@@ -1580,41 +1595,19 @@ public let CodeGenerators: [CodeGenerator] = [
1580
1595
// Generates a JavaScript 'with' statement
1581
1596
RecursiveCodeGenerator ( " WithStatementGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
1582
1597
b. buildWith ( obj) {
1583
- withProbability ( 0.5 , do: { ( ) -> Void in
1584
- let propertyName = b. type ( of: obj) . randomProperty ( ) ?? b. randomCustomPropertyName ( )
1585
- b. loadNamedVariable ( propertyName)
1586
- } , else: { ( ) -> Void in
1598
+ for i in 1 ... 3 {
1587
1599
let propertyName = b. type ( of: obj) . randomProperty ( ) ?? b. randomCustomPropertyName ( )
1588
- let value = b. randomVariable ( )
1589
- b. storeNamedVariable ( propertyName, value)
1590
- } )
1600
+ b. createNamedVariable ( propertyName, declarationMode: . none)
1601
+ }
1591
1602
b. buildRecursive ( )
1592
1603
}
1593
1604
} ,
1594
1605
1595
- CodeGenerator ( " NamedVariableLoadGenerator " ) { b in
1596
- // We're using the custom property names set from the environment for named variables.
1597
- // It's not clear if there's something better since that set should be relatively small
1598
- // (increasing the probability that named variables will be reused), and it also makes
1599
- // sense to use property names if we're inside a `with` statement.
1600
- b. loadNamedVariable ( b. randomCustomPropertyName ( ) )
1601
- } ,
1602
-
1603
- CodeGenerator ( " NamedVariableStoreGenerator " ) { b in
1604
- let value = b. randomVariable ( )
1605
- b. storeNamedVariable ( b. randomCustomPropertyName ( ) , value)
1606
- } ,
1607
-
1608
- CodeGenerator ( " NamedVariableDefinitionGenerator " ) { b in
1609
- let value = b. randomVariable ( )
1610
- b. defineNamedVariable ( b. randomCustomPropertyName ( ) , value)
1611
- } ,
1612
-
1613
1606
RecursiveCodeGenerator ( " EvalGenerator " ) { b in
1614
1607
let code = b. buildCodeString ( ) {
1615
1608
b. buildRecursive ( )
1616
1609
}
1617
- let eval = b. loadBuiltin ( " eval " )
1610
+ let eval = b. createNamedVariable ( forBuiltin : " eval " )
1618
1611
b. callFunction ( eval, withArgs: [ code] )
1619
1612
} ,
1620
1613
@@ -1629,7 +1622,7 @@ public let CodeGenerators: [CodeGenerator] = [
1629
1622
let numComputations = Int . random ( in: 3 ... 7 )
1630
1623
1631
1624
// Common mathematical operations are exposed through the Math builtin in JavaScript.
1632
- let Math = b. loadBuiltin ( " Math " )
1625
+ let Math = b. createNamedVariable ( forBuiltin : " Math " )
1633
1626
b. hide ( Math) // Following code generators should use the numbers generated below, not the Math object.
1634
1627
1635
1628
var values = b. randomVariables ( upTo: Int . random ( in: 1 ... 3 ) )
@@ -1676,7 +1669,7 @@ public let CodeGenerators: [CodeGenerator] = [
1676
1669
}
1677
1670
}
1678
1671
} else {
1679
- let toPrimitive = b. getProperty ( " toPrimitive " , of: b. loadBuiltin ( " Symbol " ) )
1672
+ let toPrimitive = b. getProperty ( " toPrimitive " , of: b. createNamedVariable ( forBuiltin : " Symbol " ) )
1680
1673
imitation = b. buildObjectLiteral { obj in
1681
1674
obj. addComputedMethod ( toPrimitive, with: . parameters( n: 0 ) ) { _ in
1682
1675
b. buildRecursive ( n: 3 )
@@ -1689,7 +1682,7 @@ public let CodeGenerators: [CodeGenerator] = [
1689
1682
// A lot of functions are also objects, so we could handle them either way. However, it probably makes more sense to handle
1690
1683
// them as a function since they would otherwise no longer be callable.
1691
1684
let handler = b. createObject ( with: [ : ] )
1692
- let Proxy = b. loadBuiltin ( " Proxy " )
1685
+ let Proxy = b. createNamedVariable ( forBuiltin : " Proxy " )
1693
1686
imitation = b. construct ( Proxy, withArgs: [ orig, handler] )
1694
1687
} else if b. type ( of: orig) . Is ( . object( ) ) {
1695
1688
// Either make a class that extends that object's constructor or make a new object with the original object as prototype.
@@ -1724,13 +1717,13 @@ public let CodeGenerators: [CodeGenerator] = [
1724
1717
if maxSize < size {
1725
1718
maxSize = size
1726
1719
}
1727
- let ArrayBuffer = b. loadBuiltin ( " ArrayBuffer " )
1720
+ let ArrayBuffer = b. createNamedVariable ( forBuiltin : " ArrayBuffer " )
1728
1721
b. hide ( ArrayBuffer)
1729
1722
let options = b. createObject ( with: [ " maxByteLength " : b. loadInt ( maxSize) ] )
1730
1723
let ab = b. construct ( ArrayBuffer, withArgs: [ b. loadInt ( size) , options] )
1731
1724
1732
- let View = b. loadBuiltin (
1733
- chooseUniform (
1725
+ let View = b. createNamedVariable (
1726
+ forBuiltin : chooseUniform (
1734
1727
from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " , " DataView " ]
1735
1728
)
1736
1729
)
@@ -1743,13 +1736,13 @@ public let CodeGenerators: [CodeGenerator] = [
1743
1736
if maxSize < size {
1744
1737
maxSize = size
1745
1738
}
1746
- let ArrayBuffer = b. loadBuiltin ( " SharedArrayBuffer " )
1739
+ let ArrayBuffer = b. createNamedVariable ( forBuiltin : " SharedArrayBuffer " )
1747
1740
b. hide ( ArrayBuffer)
1748
1741
let options = b. createObject ( with: [ " maxByteLength " : b. loadInt ( maxSize) ] )
1749
1742
let ab = b. construct ( ArrayBuffer, withArgs: [ b. loadInt ( size) , options] )
1750
1743
1751
- let View = b. loadBuiltin (
1752
- chooseUniform (
1744
+ let View = b. createNamedVariable (
1745
+ forBuiltin : chooseUniform (
1753
1746
from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " , " DataView " ]
1754
1747
)
1755
1748
)
@@ -1802,7 +1795,7 @@ public let CodeGenerators: [CodeGenerator] = [
1802
1795
} ,
1803
1796
1804
1797
CodeGenerator ( " IteratorGenerator " ) { b in
1805
- let Symbol = b. loadBuiltin ( " Symbol " )
1798
+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
1806
1799
b. hide ( Symbol)
1807
1800
let iteratorSymbol = b. getProperty ( " iterator " , of: Symbol)
1808
1801
b. hide ( iteratorSymbol)
0 commit comments