| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import Fuzzilli |
| |
| fileprivate let ForceJITCompilationThroughLoopGenerator = CodeGenerator("ForceJITCompilationThroughLoopGenerator", inputs: .required(.function())) { b, f in |
| assert(b.type(of: f).Is(.function())) |
| let arguments = b.randomArguments(forCalling: f) |
| |
| b.buildRepeatLoop(n: 100) { _ in |
| b.callFunction(f, withArgs: arguments) |
| } |
| } |
| |
| fileprivate let ForceTurboFanCompilationGenerator = CodeGenerator("ForceTurboFanCompilationGenerator", inputs: .required(.function())) { b, f in |
| assert(b.type(of: f).Is(.function())) |
| let arguments = b.randomArguments(forCalling: f) |
| |
| b.callFunction(f, withArgs: arguments) |
| |
| b.eval("%PrepareFunctionForOptimization(%@)", with: [f]); |
| |
| b.callFunction(f, withArgs: arguments) |
| b.callFunction(f, withArgs: arguments) |
| |
| b.eval("%OptimizeFunctionOnNextCall(%@)", with: [f]); |
| |
| b.callFunction(f, withArgs: arguments) |
| } |
| |
| fileprivate let ForceMaglevCompilationGenerator = CodeGenerator("ForceMaglevCompilationGenerator", inputs: .required(.function())) { b, f in |
| assert(b.type(of: f).Is(.function())) |
| let arguments = b.randomArguments(forCalling: f) |
| |
| b.callFunction(f, withArgs: arguments) |
| |
| b.eval("%PrepareFunctionForOptimization(%@)", with: [f]); |
| |
| b.callFunction(f, withArgs: arguments) |
| b.callFunction(f, withArgs: arguments) |
| |
| b.eval("%OptimizeMaglevOnNextCall(%@)", with: [f]); |
| |
| b.callFunction(f, withArgs: arguments) |
| } |
| |
| fileprivate let TurbofanVerifyTypeGenerator = CodeGenerator("TurbofanVerifyTypeGenerator", inputs: .one) { b, v in |
| b.eval("%VerifyType(%@)", with: [v]) |
| } |
| |
| // Insert random GC calls throughout our code. |
| fileprivate let GcGenerator = CodeGenerator("GcGenerator") { b in |
| let gc = b.createNamedVariable(forBuiltin: "gc") |
| |
| // Do minor GCs more frequently. |
| let type = b.loadString(probability(0.25) ? "major" : "minor") |
| // If the execution type is 'async', gc() returns a Promise, we currently |
| // do not really handle other than typing the return of gc to .undefined | |
| // .jsPromise. One could either chain a .then or create two wrapper |
| // functions that are differently typed such that fuzzilli always knows |
| // what the type of the return value is. |
| let execution = b.loadString(probability(0.5) ? "sync" : "async") |
| b.callFunction(gc, withArgs: [b.createObject(with: ["type": type, "execution": execution])]) |
| } |
| |
| public extension ILType { |
| {% for enum in database.enumerations %} |
| static let js{{enum.identifier}} = ILType.enumeration(ofName: "{{enum.identifier}}", withValues: [ {{enum.values|map("tojson")|join(", ")}} ]) |
| {% endfor %} |
| {% for interface in database.interfaces %} |
| {% set inter = interface|parse_interface -%} |
| static let js{{interface.identifier}} = {{inter[0].fuzzilli_repr()}} |
| {% endfor %} |
| {% for d in database.dictionaries %} |
| {% set dictionary = d|parse_dictionary -%} |
| static let js{{d.identifier}} = {{dictionary[0].fuzzilli_repr()}} |
| {% endfor %} |
| {% for interface in database.interfaces -%} |
| {% set constructor = interface|parse_constructors -%} |
| {% if constructor[0] %} |
| static let js{{interface.identifier}}Constructor = {{constructor[0].fuzzilli_repr()}} |
| {% endif %} |
| {%- endfor %} |
| {% for t in database.typedefs %} |
| {% set il_type = t.idl_type|idl_type_to_iltype -%} |
| static let js{{t.identifier}} = {{il_type.fuzzilli_repr()}} |
| {% endfor %} |
| {% for interface in database.callback_interfaces %} |
| {% set inter = interface|parse_interface -%} |
| static let js{{interface.identifier}} = {{inter[0].fuzzilli_repr()}} |
| {% endfor %} |
| {% for c in database.callback_functions %} |
| {% set op = c|parse_operation -%} |
| static let js{{c.identifier}} = ILType.function({{op.fuzzilli_repr()}}) |
| {% endfor %} |
| } |
| |
| {%- macro define_group(identifier, group) %} |
| let js{{identifier}} = ObjectGroup( |
| name: "{{group.name}}", |
| instanceType: {{group.instanceType.fuzzilli_repr()}}, |
| properties: [ |
| {%- for k, v in group.properties.items() %} |
| "{{k}}" : {{v.fuzzilli_repr()}}, |
| {% else %} |
| : |
| {% endfor -%} |
| ], |
| methods: [ |
| {%- for k, v in group.methods.items() %} |
| "{{k}}" : {{v.fuzzilli_repr()}}, |
| {% else %} |
| : |
| {% endfor -%} |
| ]{%- if group.parent %}, |
| parent: "{{group.parent}}" |
| {%- endif %} |
| ) |
| {%- endmacro -%} |
| |
| |
| {% for interface in database.interfaces %} |
| {%- set inter = interface|parse_interface -%} |
| {{define_group(interface.identifier, inter[1])}} |
| {% endfor %} |
| {% for interface in database.interfaces %} |
| {%- set constructor = interface|parse_constructors -%} |
| {% if constructor[1] %} |
| {{define_group(interface.identifier+"Constructor", constructor[1])}} |
| {% endif %} |
| {%- endfor %} |
| {% for d in database.dictionaries %} |
| {%- set dictionary = d|parse_dictionary -%} |
| {{define_group(d.identifier, dictionary[1])}} |
| {% endfor -%} |
| {% for interface in database.callback_interfaces %} |
| {%- set inter = interface|parse_interface -%} |
| {{define_group(interface.identifier, inter[1])}} |
| {% endfor -%} |
| |
| let chromiumProfile = Profile( |
| processArgs: { _ in |
| var args: [String] = [] |
| return args |
| }, |
| |
| processEnv: ["ASAN_OPTIONS":"detect_odr_violation=0", "DISPLAY":":20"], |
| |
| maxExecsBeforeRespawn: 100, |
| |
| timeout: 8000, |
| |
| codePrefix: """ |
| """, |
| |
| codeSuffix: """ |
| """, |
| |
| ecmaVersion: ECMAScriptVersion.es6, |
| |
| startupTests: [ |
| ("fuzzilli('FUZZILLI_CRASH', 0)", .shouldCrash), |
| ("fuzzilli('FUZZILLI_CRASH', 1)", .shouldCrash), |
| ("fuzzilli('FUZZILLI_CRASH', 2)", .shouldCrash), |
| ("fuzzilli('FUZZILLI_CRASH', 3)", .shouldCrash), |
| ], |
| |
| additionalCodeGenerators: [ |
| (ForceJITCompilationThroughLoopGenerator, 5), |
| (ForceTurboFanCompilationGenerator, 5), |
| (ForceMaglevCompilationGenerator, 5), |
| (TurbofanVerifyTypeGenerator, 10), |
| (GcGenerator, 10), |
| ], |
| |
| additionalProgramTemplates: WeightedList<ProgramTemplate>([ |
| ]), |
| |
| disabledCodeGenerators: [], |
| |
| disabledMutators: [], |
| |
| additionalBuiltins: [ |
| {%- for interface in database.interfaces -%} |
| {% set constructor = interface|parse_constructors -%} |
| {% if constructor[0] %} |
| "{{interface.identifier}}": ILType.js{{interface.identifier}}Constructor, |
| {% endif %} |
| {%- endfor %} |
| "window": .jsWindow, |
| "document": .jsDocument, |
| "gc" : .function([] => (.undefined | .jsPromise)), |
| "d8": .object(), |
| ], |
| |
| additionalObjectGroups: [ |
| {%- for interface in database.interfaces %} |
| js{{interface.identifier}}, |
| {% endfor -%} |
| {% for interface in database.interfaces -%} |
| {% set constructor = interface|parse_constructors -%} |
| {% if constructor[1] %} |
| js{{interface.identifier}}Constructor, |
| {% endif %} |
| {%- endfor -%} |
| {% for d in database.dictionaries %} |
| js{{d.identifier}}, |
| {% endfor -%} |
| {% for interface in database.callback_interfaces %} |
| js{{interface.identifier}}, |
| {% endfor -%} |
| ], |
| |
| optionalPostProcessor: nil |
| ) |