Skip to content

Commit 4e85913

Browse files
o-v8-internal-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[js, modules] implement namespaced imports and import defer
Support for "import * as ns" import syntax, including the deferred import variant. Other imports (named, default, etc.) are future work. https://github.com/tc39/proposal-defer-import-eval Bug: 398218423 Change-Id: If0e691054f0668cd4eed2bbdc9532b0c520fec4a Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/9313400 Reviewed-by: Matthias Liedtke <mliedtke@google.com> Commit-Queue: Olivier Flückiger <olivf@google.com>
1 parent 7687471 commit 4e85913

19 files changed

Lines changed: 198 additions & 7 deletions

Sources/Fuzzilli/Base/ProgramBuilder.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4336,6 +4336,12 @@ public class ProgramBuilder {
43364336
}
43374337
}
43384338

4339+
public func generateNamespaceImport() {
4340+
if let module = randomVariable(ofType: .jsModule()) {
4341+
importNamespace(module: module, isDeferred: probability(0.5))
4342+
}
4343+
}
4344+
43394345
public func exportVariables(variables: [Variable], exportNames: [String]) {
43404346
assert(variables.count == exportNames.count)
43414347
emit(ExportVariables(exportNames: exportNames), withInputs: variables)
@@ -4345,6 +4351,11 @@ public class ProgramBuilder {
43454351
return emit(ImportVariables(importNames: importNames), withInputs: [module])
43464352
}
43474353

4354+
@discardableResult
4355+
public func importNamespace(module: Variable, isDeferred: Bool) -> Instruction {
4356+
return emit(ImportNamespace(isDeferred: isDeferred), withInputs: [module])
4357+
}
4358+
43484359
public func blockBreak(_ label: Variable) {
43494360
emit(BlockBreak(), withInputs: [label], types: [.jsBlockLabel])
43504361
}

Sources/Fuzzilli/CodeGen/CodeGenerator.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,15 @@ public class GeneratorStub: Contributor {
283283
}
284284
}
285285
}
286+
287+
public func contains(_ context: Context) -> Bool {
288+
switch self {
289+
case .single(let ctx):
290+
return ctx.contains(context)
291+
case .either(let ctxs):
292+
return ctxs.contains(where: { $0.contains(context) })
293+
}
294+
}
286295
}
287296

288297
/// The contexts in which this code generator can run.

Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ public let codeGeneratorWeights = [
248248
"BundleModuleGenerator": 5,
249249
"BundleModuleEntryPointGenerator": 5,
250250
"ModuleImportGenerator": 20,
251+
"ModuleNamespaceImportGenerator": 10,
251252
"ModuleExportGenerator": 20,
252253

253254
//

Sources/Fuzzilli/CodeGen/CodeGenerators.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3615,11 +3615,14 @@ public let CodeGenerators: [CodeGenerator] = [
36153615
// TODO(marja): Add more complex imports:
36163616
// - Importing the default export
36173617
// - Non-named exports (import {v1})
3618-
// - Importing and creating a Module object
36193618
// - Dynamic imports (also in scripts)
36203619
b.generateImport()
36213620
},
36223621

3622+
CodeGenerator("ModuleNamespaceImportGenerator", inContext: .single(.moduleTopLevel)) { b in
3623+
b.generateNamespaceImport()
3624+
},
3625+
36233626
CodeGenerator("ModuleExportGenerator", inContext: .single(.moduleTopLevel)) { b in
36243627
// TODO(marja): Add more complex exports:
36253628
// - Default exports

Sources/Fuzzilli/FuzzIL/Instruction.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,10 @@ extension Instruction: ProtobufConvertible {
12541254
$0.importVariables = Fuzzilli_Protobuf_ImportVariables.with {
12551255
$0.importNames = op.importNames
12561256
}
1257+
case .importNamespace(let op):
1258+
$0.importNamespace = Fuzzilli_Protobuf_ImportNamespace.with {
1259+
$0.isDeferred = op.isDeferred
1260+
}
12571261
case .print(_):
12581262
fatalError("Print operations should not be serialized")
12591263
case .createMap(let op):
@@ -2521,6 +2525,8 @@ extension Instruction: ProtobufConvertible {
25212525
op = ExportVariables(exportNames: p.exportNames)
25222526
case .importVariables(let p):
25232527
op = ImportVariables(importNames: p.importNames)
2528+
case .importNamespace(let p):
2529+
op = ImportNamespace(isDeferred: p.isDeferred)
25242530
case .loadNewTarget:
25252531
op = LoadNewTarget()
25262532
case .nop:

Sources/Fuzzilli/FuzzIL/JSTyper.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,15 @@ public struct JSTyper: Analyzer {
21292129
set(output, exportedType)
21302130
}
21312131

2132+
case .importNamespace(_):
2133+
let moduleType = type(ofInput: 0)
2134+
let groupName = "_fuzz_Namespace\(instr.index)"
2135+
let objectGroup = ObjectGroup(
2136+
name: groupName, instanceType: nil, properties: moduleType.exports, overloads: [:]
2137+
)
2138+
dynamicObjectGroupManager.finalizedObjectGroups.append(objectGroup)
2139+
set(instr.output, objectGroup.instanceType)
2140+
21322141
case .ternaryOperation:
21332142
let outputType = type(ofInput: 1) | type(ofInput: 2)
21342143
set(instr.output, outputType)

Sources/Fuzzilli/FuzzIL/JsOperations.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,6 +3133,18 @@ final class ImportVariables: JsOperation {
31333133
}
31343134
}
31353135

3136+
final class ImportNamespace: JsOperation {
3137+
override var opcode: Opcode { .importNamespace(self) }
3138+
let isDeferred: Bool
3139+
3140+
init(isDeferred: Bool) {
3141+
self.isDeferred = isDeferred
3142+
super.init(
3143+
numInputs: 1, numOutputs: 1, attributes: [.isNotInputMutable],
3144+
requiredContext: .moduleTopLevel)
3145+
}
3146+
}
3147+
31363148
final class BeginBundleModuleEntryPoint: JsOperation {
31373149
override var opcode: Opcode { .beginBundleModuleEntryPoint(self) }
31383150

Sources/Fuzzilli/FuzzIL/Opcodes.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,5 @@ enum Opcode {
385385
case beginWorkerFunction(BeginWorkerFunction)
386386
case endWorkerFunction(EndWorkerFunction)
387387
case wasmBranchOnCast(WasmBranchOnCast)
388+
case importNamespace(ImportNamespace)
388389
}

Sources/Fuzzilli/FuzzIL/TypeSystem.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public struct ILType: Hashable {
106106
public static let dynamicObjectGroupPrefixes = [
107107
"_fuzz_Object", "_fuzz_WasmModule", "_fuzz_WasmExports", "_fuzz_Class",
108108
"_fuzz_Constructor", "_fuzz_RawWasmExports", "_fuzz_RawWasmModule",
109+
"_fuzz_Namespace",
109110
]
110111

111112
//

Sources/Fuzzilli/Lifting/FuzzILLifter.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,10 @@ public class FuzzILLifter: Lifter {
893893
let names = op.importNames.joined(separator: ", ")
894894
w.emit("\(outputs) <- ImportVariables \(input(0)), [\(names)]")
895895

896+
case .importNamespace(let op):
897+
let deferKeyword = op.isDeferred ? "defer " : ""
898+
w.emit("\(output()) <- ImportNamespace \(deferKeyword)\(input(0))")
899+
896900
case .loadNewTarget:
897901
w.emit("\(output()) <- LoadNewTarget")
898902

0 commit comments

Comments
 (0)