@@ -770,8 +770,8 @@ public class ProgramBuilder {
770770 ( . wasmTypeDef( ) , {
771771 // Call into the WasmTypeGroup generator (or other that provide a .wasmTypeDef)
772772 let generators = self . fuzzer. codeGenerators. filter { gen in
773- gen. produces. contains { type in
774- type. Is ( . wasmTypeDef( ) )
773+ gen. produces. contains { produces in
774+ produces . type. Is ( . wasmTypeDef( ) )
775775 }
776776 }
777777 let _ = self . complete ( generator: generators. randomElement ( ) , withBudget: 5 )
@@ -862,8 +862,8 @@ public class ProgramBuilder {
862862 // Right now only use generators that require a single context.
863863 $0. parts. last!. requiredContext. isSingle &&
864864 $0. parts. last!. requiredContext. satisfied ( by: self . context) &&
865- $0. parts. last!. produces. contains ( where: { producedType in
866- producedType . Is ( type)
865+ $0. parts. last!. produces. contains ( where: { produces in
866+ produces . type . Is ( type)
867867 } )
868868 } )
869869 if generators. count > 0 {
@@ -1798,14 +1798,14 @@ public class ProgramBuilder {
17981798 struct BuildAction {
17991799 var name : String
18001800 var outcome = ActionOutcome . started
1801- var produces : [ ILType ]
1801+ var produces : [ GeneratorStub . Constraint ]
18021802 }
18031803
18041804 var pendingActions : Stack < BuildAction > = Stack ( )
18051805 var actions = [ ( BuildAction, Int) ] ( )
18061806 var indent = 0
18071807
1808- mutating func startAction( _ actionName: String , produces: [ ILType ] ) {
1808+ mutating func startAction( _ actionName: String , produces: [ GeneratorStub . Constraint ] ) {
18091809 let action = BuildAction ( name: actionName, produces: produces)
18101810 // Mark this action as `.started`.
18111811 actions. append ( ( action, indent) )
@@ -1820,16 +1820,14 @@ public class ProgramBuilder {
18201820 finishedAction. outcome = . success
18211821 actions. append ( ( finishedAction, indent) )
18221822 #if DEBUG
1823- // Now Check that we've seen these new types.
1824- for t in finishedAction. produces {
1825- if !newlyCreatedVariableTypes. contains ( where: {
1826- $0. Is ( t)
1827- } ) {
1823+ // Now Check that we have variables that match the the specified productions.
1824+ for requirement in finishedAction. produces {
1825+ if !newlyCreatedVariableTypes. contains ( where: requirement. fulfilled) {
18281826 var fatalErrorString = " "
18291827 fatalErrorString += " Action: \( finishedAction. name) \n "
18301828 fatalErrorString += " Action guaranteed it would produce: \( finishedAction. produces) \n "
18311829 fatalErrorString += " \( getLogString ( ) ) \n "
1832- fatalErrorString += " newlyCreatedVariableTypes: \( newlyCreatedVariableTypes) does not contain expected type \( t ) "
1830+ fatalErrorString += " newlyCreatedVariableTypes: \( newlyCreatedVariableTypes) does not contain anything matching \( requirement ) "
18331831 fatalError ( fatalErrorString)
18341832 }
18351833 }
@@ -2113,31 +2111,29 @@ public class ProgramBuilder {
21132111 var numberOfGeneratedInstructions = 0
21142112
21152113 // Calculate all input requirements of this CodeGenerator.
2116- let inputTypes = Set ( generator. parts. reduce ( [ ] ) { res, gen in
2117- return res + gen. inputs. types
2114+ let inputRequirements = Set ( generator. parts. reduce ( [ ] ) { res, gen in
2115+ return res + gen. inputs. constraints
21182116 } )
21192117
2120- var availableTypes = inputTypes . filter {
2121- randomVariable ( ofType : $0) != nil
2118+ var fulfilledRequirements = inputRequirements . filter { requirement in
2119+ findVariable { requirement . fulfilled ( by : self . type ( of : $0) ) } != nil
21222120 }
21232121
21242122 // Add the current context to the seen Contexts as well.
21252123 var seenContexts : [ Context ] = [ context]
21262124
2127- let contextsAndTypes = generator. parts. map { ( $0. providedContext, $0. inputs. types ) }
2125+ let contextsAndRequirements = generator. parts. map { ( $0. providedContext, $0. inputs. constraints ) }
21282126
21292127 // Check if the can be produced along this generator, otherwise we need to bail.
2130- for (contexts, types ) in contextsAndTypes {
2128+ for (contexts, requirements ) in contextsAndRequirements {
21312129 // We've seen the current context.
21322130 for context in contexts {
21332131 seenContexts. append ( context)
21342132 }
21352133
2136- for type in types {
2134+ for requirement in requirements {
21372135 // If we don't have the type available, check if we can produce it in the current context or a seen context.
2138- if !availableTypes. contains ( where: {
2139- type. Is ( $0)
2140- } ) {
2136+ if !fulfilledRequirements. contains ( where: requirement. fulfilled) {
21412137 // Check if we have generators that can produce the type reachable from this context.
21422138 let reachableContexts : Context = seenContexts. reduce ( Context . empty) { res, ctx in [ res, fuzzer. contextGraph. getReachableContexts ( from: ctx) . reduce ( Context . empty) { res, ctx in [ res, ctx] } ]
21432139 }
@@ -2151,25 +2147,25 @@ public class ProgramBuilder {
21512147
21522148 // Filter to see if they produce this type. Crucially to avoid dependency cycles, these also need to be valuegenerators.
21532149 let canProduceThisType = callableGenerators. contains ( where: { generator in
2154- generator. produces. contains ( where: { $0 . Is ( type ) } )
2150+ generator. produces. contains ( where: { requirement . fulfilled ( by : $0 ) } )
21552151 } )
21562152
21572153 // We cannot run if this is false.
21582154 if !canProduceThisType {
21592155 // TODO(cffsmith): track some statistics on how often this happens.
2160- buildLog? . reportFailure ( reason: " Cannot produce type \( type ) starting in original context \( context) . " )
2156+ buildLog? . reportFailure ( reason: " Cannot produce type \( requirement ) starting in original context \( context) . " )
21612157 return 0
21622158 } else {
21632159 // Mark the type as available.
2164- availableTypes . insert ( type )
2160+ fulfilledRequirements . insert ( requirement )
21652161 }
21662162 }
21672163 }
21682164 }
21692165
21702166 // Try to create the types that we need for this generator.
21712167 // At this point we've guaranteed that we can produce the types somewhere along the yield points of this generator.
2172- createRequiredInputVariables ( forTypes : inputTypes )
2168+ createRequiredInputVariables ( for : inputRequirements )
21732169
21742170 // Push the remaining stubs, we need to call them to close all Contexts properly.
21752171 for part in generator. tail. reversed ( ) {
@@ -2191,7 +2187,7 @@ public class ProgramBuilder {
21912187 while scheduled. count > depth {
21922188 let codeSizePre = code. count
21932189 // Check if we need to or can create types here.
2194- createRequiredInputVariables ( forTypes : inputTypes )
2190+ createRequiredInputVariables ( for : inputRequirements )
21952191 // Build into the block.
21962192 buildRecursive ( n: budgetPerYieldPoint)
21972193 // Call the next scheduled stub.
@@ -2215,22 +2211,22 @@ public class ProgramBuilder {
22152211 }
22162212
22172213 // Todo, the context graph could also find ideal paths that allow type creation.
2218- private func createRequiredInputVariables( forTypes types: Set < ILType > ) {
2219- for type in types {
2214+ private func createRequiredInputVariables( for requirements: Set < GeneratorStub . Constraint > ) {
2215+ for requirement in requirements {
2216+ let type = requirement. type
22202217 if type. Is ( . jsAnything) && context. contains ( . javascript) {
22212218 let _ = findOrGenerateType ( type)
22222219 } else {
22232220 if type. Is ( . wasmAnything) && context. contains ( . wasmFunction) {
22242221 // Check if we can produce it with findOrGenerateWasmVar
22252222 let _ = currentWasmFunction. generateRandomWasmVar ( ofType: type)
22262223 }
2227- if randomVariable ( ofType: type) == nil {
2224+ if ( findVariable { requirement. fulfilled ( by: self . type ( of: $0) ) } == nil ) {
2225+
22282226 // Check for other CodeGenerators that can produce the given type in this context.
22292227 let usableGenerators = fuzzer. codeGenerators. filter {
22302228 $0. requiredContext. isSubset ( of: context) &&
2231- $0. produces. contains {
2232- $0. Is ( type)
2233- }
2229+ $0. produces. contains ( where: requirement. fulfilled)
22342230 }
22352231
22362232 // Cannot build type here.
@@ -2344,18 +2340,18 @@ public class ProgramBuilder {
23442340 switch generator. inputs. mode {
23452341 case . loose:
23462342 // Find inputs that are probably compatible with the desired input types using randomVariable(forUseAs:)
2347- inputs = generator. inputs. types . map ( randomVariable ( forUseAs: ) )
2343+ inputs = generator. inputs. constraints . map { randomVariable ( forUseAs: $0 . type ) }
23482344
23492345 case . strict:
23502346 // Find inputs of the required type using randomVariable(ofType:)
2351- for inputType in generator. inputs. types {
2352- guard let input = randomVariable ( ofType : inputType ) else {
2347+ for requirement in generator. inputs. constraints {
2348+ guard let input = ( findVariable { requirement . fulfilled ( by : self . type ( of : $0 ) ) } ) else {
23532349 // Cannot run this generator
23542350 if generator. providedContext != [ ] {
23552351 fatalError ( " This generator is supposed to provide a context but cannot as we've failed to find the necessary inputs. " )
23562352 }
23572353 // This early return also needs to report a failure.
2358- buildLog? . reportFailure ( reason: " Cannot find variable that satifies input constraints \( inputType ) . " )
2354+ buildLog? . reportFailure ( reason: " Cannot find variable that satifies input constraints \( requirement . type ) . " )
23592355 return 0
23602356 }
23612357 inputs. append ( input)
0 commit comments