@@ -100,7 +100,7 @@ public let CodeGenerators: [CodeGenerator] = [
100100
101101 ValueGenerator ( " BuiltinObjectInstanceGenerator " ) { b, n in
102102 let builtin = chooseUniform ( from: [ " Array " , " Map " , " WeakMap " , " Set " , " WeakSet " , " Date " ] )
103- let constructor = b. loadBuiltin ( builtin)
103+ let constructor = b. createNamedVariable ( forBuiltin : builtin)
104104 if builtin == " Array " {
105105 let size = b. loadInt ( b. randomSize ( upTo: 0x1000 ) )
106106 b. construct ( constructor, withArgs: [ size] )
@@ -113,8 +113,8 @@ public let CodeGenerators: [CodeGenerator] = [
113113 ValueGenerator ( " TypedArrayGenerator " ) { b, n in
114114 for _ in 0 ..< n {
115115 let size = b. loadInt ( b. randomSize ( upTo: 0x1000 ) )
116- let constructor = b. loadBuiltin (
117- chooseUniform (
116+ let constructor = b. createNamedVariable (
117+ forBuiltin : chooseUniform (
118118 from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " ]
119119 )
120120 )
@@ -277,7 +277,7 @@ public let CodeGenerators: [CodeGenerator] = [
277277
278278 CodeGenerator ( " DisposableVariableGenerator " , inContext: . subroutine, inputs: . one) { b, val in
279279 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 " ) ) ;
281281 let disposableVariable = b. buildObjectLiteral { obj in
282282 obj. addProperty ( " value " , as: val)
283283 obj. addComputedMethod ( dispose, with: . parameters( n: 0 ) ) { args in
@@ -289,7 +289,7 @@ public let CodeGenerators: [CodeGenerator] = [
289289
290290 CodeGenerator ( " AsyncDisposableVariableGenerator " , inContext: . asyncFunction, inputs: . one) { b, val in
291291 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 " ) )
293293 let asyncDisposableVariable = b. buildObjectLiteral { obj in
294294 obj. addProperty ( " value " , as: val)
295295 obj. addComputedMethod ( asyncDispose, with: . parameters( n: 0 ) ) { args in
@@ -770,11 +770,26 @@ public let CodeGenerators: [CodeGenerator] = [
770770
771771 // We don't treat this as a ValueGenerator since it doesn't create a new value, it only accesses an existing one.
772772 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+ }
774788 } ,
775789
776790 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)
778793 } ,
779794
780795 RecursiveCodeGenerator ( " PlainFunctionGenerator " ) { b in
@@ -1477,7 +1492,7 @@ public let CodeGenerators: [CodeGenerator] = [
14771492 //
14781493
14791494 CodeGenerator ( " WellKnownPropertyLoadGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
1480- let Symbol = b. loadBuiltin ( " Symbol " )
1495+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
14811496 // The Symbol constructor is just a "side effect" of this generator and probably shouldn't be used by following generators.
14821497 b. hide ( Symbol)
14831498 let name = chooseUniform ( from: JavaScriptEnvironment . wellKnownSymbols)
@@ -1486,7 +1501,7 @@ public let CodeGenerators: [CodeGenerator] = [
14861501 } ,
14871502
14881503 CodeGenerator ( " WellKnownPropertyStoreGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
1489- let Symbol = b. loadBuiltin ( " Symbol " )
1504+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
14901505 b. hide ( Symbol)
14911506 let name = chooseUniform ( from: JavaScriptEnvironment . wellKnownSymbols)
14921507 let propertyName = b. getProperty ( name, of: Symbol)
@@ -1511,13 +1526,13 @@ public let CodeGenerators: [CodeGenerator] = [
15111526 CodeGenerator ( " MethodCallWithDifferentThisGenerator " , inputs: . preferred( . object( ) , . object( ) ) ) { b, obj, this in
15121527 guard let methodName = b. type ( of: obj) . randomMethod ( ) else { return }
15131528 let arguments = b. randomArguments ( forCallingMethod: methodName, on: obj)
1514- let Reflect = b. loadBuiltin ( " Reflect " )
1529+ let Reflect = b. createNamedVariable ( forBuiltin : " Reflect " )
15151530 let args = b. createArray ( with: arguments)
15161531 b. callMethod ( " apply " , on: Reflect, withArgs: [ b. getProperty ( methodName, of: obj) , this, args] )
15171532 } ,
15181533
15191534 CodeGenerator ( " ConstructWithDifferentNewTargetGenerator " , inputs: . preferred( . constructor( ) , . constructor( ) ) ) { b, newTarget, constructor in
1520- let reflect = b. loadBuiltin ( " Reflect " )
1535+ let reflect = b. createNamedVariable ( forBuiltin : " Reflect " )
15211536 let arguments = [ constructor, b. createArray ( with: b. randomArguments ( forCalling: constructor) ) , newTarget]
15221537 b. callMethod ( " construct " , on: reflect, withArgs: arguments)
15231538 } ,
@@ -1543,7 +1558,7 @@ public let CodeGenerators: [CodeGenerator] = [
15431558 }
15441559 let handler = b. createObject ( with: handlerProperties)
15451560
1546- let Proxy = b. loadBuiltin ( " Proxy " )
1561+ let Proxy = b. createNamedVariable ( forBuiltin : " Proxy " )
15471562 b. hide ( Proxy) // We want the proxy to be used by following code generators, not the Proxy constructor
15481563 b. construct ( Proxy, withArgs: [ target, handler] )
15491564 } ,
@@ -1553,7 +1568,7 @@ public let CodeGenerators: [CodeGenerator] = [
15531568 // TODO could provide type hints here for the parameters.
15541569 b. buildRecursive ( )
15551570 }
1556- let Promise = b. loadBuiltin ( " Promise " )
1571+ let Promise = b. createNamedVariable ( forBuiltin : " Promise " )
15571572 b. hide ( Promise) // We want the promise to be used by following code generators, not the Promise constructor
15581573 b. construct ( Promise, withArgs: [ handler] )
15591574 } ,
@@ -1580,41 +1595,19 @@ public let CodeGenerators: [CodeGenerator] = [
15801595 // Generates a JavaScript 'with' statement
15811596 RecursiveCodeGenerator ( " WithStatementGenerator " , inputs: . preferred( . object( ) ) ) { b, obj in
15821597 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 {
15871599 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+ }
15911602 b. buildRecursive ( )
15921603 }
15931604 } ,
15941605
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-
16131606 RecursiveCodeGenerator ( " EvalGenerator " ) { b in
16141607 let code = b. buildCodeString ( ) {
16151608 b. buildRecursive ( )
16161609 }
1617- let eval = b. loadBuiltin ( " eval " )
1610+ let eval = b. createNamedVariable ( forBuiltin : " eval " )
16181611 b. callFunction ( eval, withArgs: [ code] )
16191612 } ,
16201613
@@ -1629,7 +1622,7 @@ public let CodeGenerators: [CodeGenerator] = [
16291622 let numComputations = Int . random ( in: 3 ... 7 )
16301623
16311624 // Common mathematical operations are exposed through the Math builtin in JavaScript.
1632- let Math = b. loadBuiltin ( " Math " )
1625+ let Math = b. createNamedVariable ( forBuiltin : " Math " )
16331626 b. hide ( Math) // Following code generators should use the numbers generated below, not the Math object.
16341627
16351628 var values = b. randomVariables ( upTo: Int . random ( in: 1 ... 3 ) )
@@ -1676,7 +1669,7 @@ public let CodeGenerators: [CodeGenerator] = [
16761669 }
16771670 }
16781671 } else {
1679- let toPrimitive = b. getProperty ( " toPrimitive " , of: b. loadBuiltin ( " Symbol " ) )
1672+ let toPrimitive = b. getProperty ( " toPrimitive " , of: b. createNamedVariable ( forBuiltin : " Symbol " ) )
16801673 imitation = b. buildObjectLiteral { obj in
16811674 obj. addComputedMethod ( toPrimitive, with: . parameters( n: 0 ) ) { _ in
16821675 b. buildRecursive ( n: 3 )
@@ -1689,7 +1682,7 @@ public let CodeGenerators: [CodeGenerator] = [
16891682 // A lot of functions are also objects, so we could handle them either way. However, it probably makes more sense to handle
16901683 // them as a function since they would otherwise no longer be callable.
16911684 let handler = b. createObject ( with: [ : ] )
1692- let Proxy = b. loadBuiltin ( " Proxy " )
1685+ let Proxy = b. createNamedVariable ( forBuiltin : " Proxy " )
16931686 imitation = b. construct ( Proxy, withArgs: [ orig, handler] )
16941687 } else if b. type ( of: orig) . Is ( . object( ) ) {
16951688 // 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] = [
17241717 if maxSize < size {
17251718 maxSize = size
17261719 }
1727- let ArrayBuffer = b. loadBuiltin ( " ArrayBuffer " )
1720+ let ArrayBuffer = b. createNamedVariable ( forBuiltin : " ArrayBuffer " )
17281721 b. hide ( ArrayBuffer)
17291722 let options = b. createObject ( with: [ " maxByteLength " : b. loadInt ( maxSize) ] )
17301723 let ab = b. construct ( ArrayBuffer, withArgs: [ b. loadInt ( size) , options] )
17311724
1732- let View = b. loadBuiltin (
1733- chooseUniform (
1725+ let View = b. createNamedVariable (
1726+ forBuiltin : chooseUniform (
17341727 from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " , " DataView " ]
17351728 )
17361729 )
@@ -1743,13 +1736,13 @@ public let CodeGenerators: [CodeGenerator] = [
17431736 if maxSize < size {
17441737 maxSize = size
17451738 }
1746- let ArrayBuffer = b. loadBuiltin ( " SharedArrayBuffer " )
1739+ let ArrayBuffer = b. createNamedVariable ( forBuiltin : " SharedArrayBuffer " )
17471740 b. hide ( ArrayBuffer)
17481741 let options = b. createObject ( with: [ " maxByteLength " : b. loadInt ( maxSize) ] )
17491742 let ab = b. construct ( ArrayBuffer, withArgs: [ b. loadInt ( size) , options] )
17501743
1751- let View = b. loadBuiltin (
1752- chooseUniform (
1744+ let View = b. createNamedVariable (
1745+ forBuiltin : chooseUniform (
17531746 from: [ " Uint8Array " , " Int8Array " , " Uint16Array " , " Int16Array " , " Uint32Array " , " Int32Array " , " Float32Array " , " Float64Array " , " Uint8ClampedArray " , " BigInt64Array " , " BigUint64Array " , " DataView " ]
17541747 )
17551748 )
@@ -1802,7 +1795,7 @@ public let CodeGenerators: [CodeGenerator] = [
18021795 } ,
18031796
18041797 CodeGenerator ( " IteratorGenerator " ) { b in
1805- let Symbol = b. loadBuiltin ( " Symbol " )
1798+ let Symbol = b. createNamedVariable ( forBuiltin : " Symbol " )
18061799 b. hide ( Symbol)
18071800 let iteratorSymbol = b. getProperty ( " iterator " , of: Symbol)
18081801 b. hide ( iteratorSymbol)
0 commit comments