1// Copyright 2024 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import Fuzzilli 6 7fileprivate let ForceJITCompilationThroughLoopGenerator = CodeGenerator("ForceJITCompilationThroughLoopGenerator", inputs: .required(.function())) { b, f in 8 assert(b.type(of: f).Is(.function())) 9 let arguments = b.randomArguments(forCalling: f) 10 11 b.buildRepeatLoop(n: 100) { _ in 12 b.callFunction(f, withArgs: arguments) 13 } 14} 15 16fileprivate let ForceTurboFanCompilationGenerator = CodeGenerator("ForceTurboFanCompilationGenerator", inputs: .required(.function())) { b, f in 17 assert(b.type(of: f).Is(.function())) 18 let arguments = b.randomArguments(forCalling: f) 19 20 b.callFunction(f, withArgs: arguments) 21 22 b.eval("%PrepareFunctionForOptimization(%@)", with: [f]); 23 24 b.callFunction(f, withArgs: arguments) 25 b.callFunction(f, withArgs: arguments) 26 27 b.eval("%OptimizeFunctionOnNextCall(%@)", with: [f]); 28 29 b.callFunction(f, withArgs: arguments) 30} 31 32fileprivate let ForceMaglevCompilationGenerator = CodeGenerator("ForceMaglevCompilationGenerator", inputs: .required(.function())) { b, f in 33 assert(b.type(of: f).Is(.function())) 34 let arguments = b.randomArguments(forCalling: f) 35 36 b.callFunction(f, withArgs: arguments) 37 38 b.eval("%PrepareFunctionForOptimization(%@)", with: [f]); 39 40 b.callFunction(f, withArgs: arguments) 41 b.callFunction(f, withArgs: arguments) 42 43 b.eval("%OptimizeMaglevOnNextCall(%@)", with: [f]); 44 45 b.callFunction(f, withArgs: arguments) 46} 47 48fileprivate let TurbofanVerifyTypeGenerator = CodeGenerator("TurbofanVerifyTypeGenerator", inputs: .one) { b, v in 49 b.eval("%VerifyType(%@)", with: [v]) 50} 51 52// Insert random GC calls throughout our code. 53fileprivate let GcGenerator = CodeGenerator("GcGenerator") { b in 54 let gc = b.loadBuiltin("gc") 55 56 // Do minor GCs more frequently. 57 let type = b.loadString(probability(0.25) ? "major" : "minor") 58 // If the execution type is 'async', gc() returns a Promise, we currently 59 // do not really handle other than typing the return of gc to .undefined | 60 // .jsPromise. One could either chain a .then or create two wrapper 61 // functions that are differently typed such that fuzzilli always knows 62 // what the type of the return value is. 63 let execution = b.loadString(probability(0.5) ? "sync" : "async") 64 b.callFunction(gc, withArgs: [b.createObject(with: ["type": type, "execution": execution])]) 65} 66 67public extension ILType { 68{% for enum in database.enumerations %} 69 static let js{{enum.identifier}} = ILType.string 70{% endfor %} 71{% for interface in database.interfaces %} 72 {% set inter = interface|parse_interface -%} 73 static let js{{interface.identifier}} = {{inter[0].fuzzilli_repr()}} 74{% endfor %} 75{% for d in database.dictionaries %} 76 {% set dictionary = d|parse_dictionary -%} 77 static let js{{d.identifier}} = {{dictionary[0].fuzzilli_repr()}} 78{% endfor %} 79{% for interface in database.interfaces -%} 80 {% set constructor = interface|parse_constructors -%} 81{% if constructor[0] %} 82 static let js{{interface.identifier}}Constructor = {{constructor[0].fuzzilli_repr()}} 83{% endif %} 84{%- endfor %} 85{% for t in database.typedefs %} 86 {% set il_type = t.idl_type|idl_type_to_iltype -%} 87 static let js{{t.identifier}} = {{il_type.fuzzilli_repr()}} 88{% endfor %} 89{% for interface in database.callback_interfaces %} 90 {% set inter = interface|parse_interface -%} 91 static let js{{interface.identifier}} = {{inter[0].fuzzilli_repr()}} 92{% endfor %} 93{% for c in database.callback_functions %} 94 {% set op = c|parse_operation -%} 95 static let js{{c.identifier}} = ILType.function({{op.fuzzilli_repr()}}) 96{% endfor %} 97} 98 99{%- macro define_group(identifier, group) %} 100let js{{identifier}} = ObjectGroup( 101 name: "{{group.name}}", 102 instanceType: {{group.instanceType.fuzzilli_repr()}}, 103 properties: [ 104 {%- for k, v in group.properties.items() %} 105 "{{k}}" : {{v.fuzzilli_repr()}}, 106 {% else %} 107 : 108 {% endfor -%} 109 ], 110 methods: [ 111 {%- for k, v in group.methods.items() %} 112 "{{k}}" : {{v.fuzzilli_repr()}}, 113 {% else %} 114 : 115 {% endfor -%} 116 ] 117) 118{%- endmacro -%} 119 120 121{% for interface in database.interfaces %} 122 {%- set inter = interface|parse_interface -%} 123{{define_group(interface.identifier, inter[1])}} 124{% endfor %} 125{% for interface in database.interfaces %} 126 {%- set constructor = interface|parse_constructors -%} 127{% if constructor[1] %} 128{{define_group(interface.identifier+"Constructor", constructor[1])}} 129{% endif %} 130{%- endfor %} 131{% for d in database.dictionaries %} 132 {%- set dictionary = d|parse_dictionary -%} 133{{define_group(d.identifier, dictionary[1])}} 134{% endfor -%} 135{% for interface in database.callback_interfaces %} 136 {%- set inter = interface|parse_interface -%} 137{{define_group(interface.identifier, inter[1])}} 138{% endfor -%} 139 140let chromiumProfile = Profile( 141 processArgs: { _ in 142 var args: [String] = [] 143 return args 144 }, 145 146 processEnv: ["ASAN_OPTIONS":"detect_odr_violation=0", "DISPLAY":":20"], 147 148 maxExecsBeforeRespawn: 100, 149 150 timeout: 8000, 151 152 codePrefix: """ 153 """, 154 155 codeSuffix: """ 156 """, 157 158 ecmaVersion: ECMAScriptVersion.es6, 159 160 startupTests: [ 161 ("fuzzilli('FUZZILLI_CRASH', 0)", .shouldCrash), 162 ("fuzzilli('FUZZILLI_CRASH', 1)", .shouldCrash), 163 ("fuzzilli('FUZZILLI_CRASH', 2)", .shouldCrash), 164 ("fuzzilli('FUZZILLI_CRASH', 3)", .shouldCrash), 165 ], 166 167 additionalCodeGenerators: [ 168 (ForceJITCompilationThroughLoopGenerator, 5), 169 (ForceTurboFanCompilationGenerator, 5), 170 (ForceMaglevCompilationGenerator, 5), 171 (TurbofanVerifyTypeGenerator, 10), 172 (GcGenerator, 10), 173 ], 174 175 additionalProgramTemplates: WeightedList<ProgramTemplate>([ 176 ]), 177 178 disabledCodeGenerators: [], 179 180 disabledMutators: [], 181 182 additionalBuiltins: [ 183{%- for interface in database.interfaces -%} 184 {% set constructor = interface|parse_constructors -%} 185{% if constructor[0] %} 186 "{{interface.identifier}}": ILType.js{{interface.identifier}}Constructor, 187{% endif %} 188{%- endfor %} 189 "window": .jsWindow, 190 "document": .jsDocument, 191 "gc" : .function([] => (.undefined | .jsPromise)), 192 "d8": .object(), 193 ], 194 195 additionalObjectGroups: [ 196{%- for interface in database.interfaces %} 197 js{{interface.identifier}}, 198{% endfor -%} 199{% for interface in database.interfaces -%} 200 {% set constructor = interface|parse_constructors -%} 201{% if constructor[1] %} 202 js{{interface.identifier}}Constructor, 203{% endif %} 204{%- endfor -%} 205{% for d in database.dictionaries %} 206 js{{d.identifier}}, 207{% endfor -%} 208{% for interface in database.callback_interfaces %} 209 js{{interface.identifier}}, 210{% endfor -%} 211 ], 212 213 optionalPostProcessor: nil 214) 215