Skip to content

Commit 672b969

Browse files
Dominik KlembaV8-internal LUCI CQ
authored andcommitted
Add shared memory support to WasmDefineMemoryGenerator
Adds support for generating shared WebAssembly memory. Extends existing tests to cover shared memory cases. Change-Id: I381cf34af9fa04aad8a559d4703d1a3f3a6680c6 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/8457856 Reviewed-by: Matthias Liedtke <[email protected]> Commit-Queue: Dominik Klemba <[email protected]>
1 parent 1d22d0e commit 672b969

File tree

7 files changed

+44
-26
lines changed

7 files changed

+44
-26
lines changed

Sources/Fuzzilli/Base/ProgramBuilder.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,6 +2955,7 @@ public class ProgramBuilder {
29552955

29562956
@discardableResult
29572957
public func createWasmMemory(minPages: Int, maxPages: Int? = nil, isShared: Bool = false, isMemory64: Bool = false) -> Variable {
2958+
assert(!isShared || maxPages != nil, "Shared memories must have a maximum size")
29582959
return emit(CreateWasmMemory(limits: Limits(min: minPages, max: maxPages), isShared: isShared, isMemory64: isMemory64)).output
29592960
}
29602961

Sources/Fuzzilli/CodeGen/WasmCodeGenerators.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ public let WasmCodeGenerators: [CodeGenerator] = [
2828

2929
CodeGenerator("WasmMemoryGenerator", inContext: .javascript) { b in
3030
let minPages = Int.random(in: 0..<10)
31+
let isShared = probability(0.5)
3132
var maxPages: Int? = nil
32-
if probability(0.5) {
33+
if isShared || probability(0.5) {
3334
maxPages = Int.random(in: minPages...WasmConstants.specMaxWasmMem32Pages)
3435
}
35-
b.createWasmMemory(minPages: minPages, maxPages: maxPages, isShared: probability(0.5))
36+
b.createWasmMemory(minPages: minPages, maxPages: maxPages, isShared: isShared)
3637
},
3738

3839
CodeGenerator("WasmTagGenerator", inContext: .javascript) { b in
@@ -295,21 +296,22 @@ public let WasmCodeGenerators: [CodeGenerator] = [
295296

296297
// Memory Generators
297298

298-
// TODO: support shared memories.
299299
CodeGenerator("WasmDefineMemoryGenerator", inContext: .wasm) { b in
300300
let module = b.currentWasmModule
301301

302+
let isShared = probability(0.5)
302303
let isMemory64 = probability(0.5)
303304

304305
let minPages = Int.random(in: 1..<10)
305306
let maxPages: Int?
306-
if probability(0.5) {
307+
// Shared memories always need to specify a maximum size.
308+
if !isShared && probability(0.5) {
307309
maxPages = nil
308310
} else {
309311
maxPages = Int.random(in: minPages...(isMemory64 ? WasmConstants.specMaxWasmMem64Pages
310312
: WasmConstants.specMaxWasmMem32Pages))
311313
}
312-
module.addMemory(minPages: minPages, maxPages: maxPages, isShared: false, isMemory64: isMemory64)
314+
module.addMemory(minPages: minPages, maxPages: maxPages, isShared: isShared, isMemory64: isMemory64)
313315
},
314316

315317
CodeGenerator("WasmMemoryLoadGenerator", inContext: .wasmFunction, inputs: .required(.object(ofGroup: "WasmMemory"))) { b, memory in

Sources/Fuzzilli/FuzzIL/TypeSystem.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,7 @@ public class WasmMemoryType: WasmTypeExtension {
16011601
}
16021602

16031603
init(limits: Limits, isShared: Bool = false, isMemory64: Bool = false) {
1604+
assert(!isShared || limits.max != nil, "Shared memories must have a maximum size")
16041605
self.limits = limits
16051606
self.isShared = isShared
16061607
self.isMemory64 = isMemory64

Sources/Fuzzilli/Lifting/JavaScriptLifter.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,8 +1414,12 @@ public class JavaScriptLifter: Lifter {
14141414
if let maxPages = op.memType.limits.max {
14151415
maxPagesStr = ", maximum: \(maxPages)" + (isMemory64 ? "n" : "")
14161416
}
1417+
var sharedStr = ""
1418+
if op.memType.isShared {
1419+
sharedStr = ", shared: true"
1420+
}
14171421
let addressType = isMemory64 ? "'i64'" : "'i32'"
1418-
w.emit("\(LET) \(V) = new WebAssembly.Memory({ initial: \(minPageStr)\(maxPagesStr), address: \(addressType) });")
1422+
w.emit("\(LET) \(V) = new WebAssembly.Memory({ initial: \(minPageStr)\(maxPagesStr)\(sharedStr), address: \(addressType) });")
14191423

14201424
case .wrapSuspending(_):
14211425
let V = w.declare(instr.output)

Tests/FuzzilliTests/JSTyperTests.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,7 @@ class JSTyperTests: XCTestCase {
15081508
XCTAssertEqual(b.type(ofProperty: "bla", on: object), .integer)
15091509
}
15101510

1511-
func testDynamicObjectGroupTypingOfWasmModules() {
1511+
func dynamicObjectGroupTypingOfWasmModulesTestCase(isShared: Bool) {
15121512
let liveTestConfig = Configuration(logLevel: .error, enableInspection: true)
15131513

15141514
// We have to use the proper JavaScriptEnvironment here.
@@ -1520,7 +1520,8 @@ class JSTyperTests: XCTestCase {
15201520
let wasmGlobalf64: Variable = b.createWasmGlobal(value: .wasmf64(1337), isMutable: false)
15211521
XCTAssertEqual(b.type(of: wasmGlobalf64), .object(ofGroup: "WasmGlobal", withProperties: ["value"], withWasmType: WasmGlobalType(valueType: ILType.wasmf64, isMutable: false)))
15221522

1523-
let memory = b.createWasmMemory(minPages: 1)
1523+
let maxPages: Int? = isShared ? 4 : nil
1524+
let memory = b.createWasmMemory(minPages: 1, maxPages: maxPages, isShared: isShared)
15241525
let jsTag = b.createWasmJSTag()
15251526

15261527
let typeGroup = b.wasmDefineTypeGroup {
@@ -1540,7 +1541,7 @@ class JSTyperTests: XCTestCase {
15401541
// Defines one global
15411542
wasmModule.addGlobal(wasmGlobal: .wasmi64(1339), isMutable: true)
15421543

1543-
wasmModule.addMemory(minPages: 3)
1544+
wasmModule.addMemory(minPages: 3, maxPages: maxPages, isShared: isShared)
15441545

15451546
wasmModule.addTag(parameterTypes: [.wasmi32])
15461547

@@ -1615,17 +1616,22 @@ class JSTyperTests: XCTestCase {
16151616
XCTAssertEqual(b.type(of: glob1), .object(ofGroup: "WasmGlobal", withProperties: ["value"], withWasmType: WasmGlobalType(valueType: .wasmf64, isMutable: false)))
16161617

16171618
let mem0 = b.getProperty("wm0", of: exports)
1618-
let memType = ILType.wasmMemory(limits: Limits(min: 3))
1619+
let memType = ILType.wasmMemory(limits: Limits(min: 3, max: maxPages), isShared: isShared)
16191620
XCTAssertEqual(b.type(of: mem0), memType)
16201621

16211622
let importedMem = b.getProperty("iwm0", of: exports)
1622-
let importedMemType = ILType.wasmMemory(limits: Limits(min: 1))
1623+
let importedMemType = ILType.wasmMemory(limits: Limits(min: 1, max: maxPages), isShared: isShared)
16231624
XCTAssertEqual(b.type(of: importedMem), importedMemType)
16241625

16251626
let reexportedJsTag = b.getProperty("iwex0", of: exports)
16261627
XCTAssertEqual(b.type(of: reexportedJsTag), b.type(of: jsTag))
16271628
}
16281629

1630+
func testDynamicObjectGroupTypingOfWasmModules() {
1631+
dynamicObjectGroupTypingOfWasmModulesTestCase(isShared: false)
1632+
dynamicObjectGroupTypingOfWasmModulesTestCase(isShared: true)
1633+
}
1634+
16291635
func testBuiltinPrototypes() {
16301636
let fuzzer = makeMockFuzzer()
16311637
let b = fuzzer.makeBuilder()

Tests/FuzzilliTests/WasmAtomicsTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class WasmAtomicsTests: XCTestCase {
2626
var expectedOutput = ""
2727

2828
let module = b.buildWasmModule { wasmModule in
29-
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: false)
30-
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: true)
29+
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: false)
30+
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: true)
3131

3232
for memory in [unsharedMemory, sharedMemory] {
3333
wasmModule.addWasmFunction(with: [] => [.wasmi32]) { f, _, _ in
@@ -83,8 +83,8 @@ class WasmAtomicsTests: XCTestCase {
8383

8484
let module = b.buildWasmModule {
8585
wasmModule in
86-
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: false)
87-
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: true)
86+
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: false)
87+
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: true)
8888

8989
for memory in [unsharedMemory, sharedMemory] {
9090
wasmModule.addWasmFunction(with: [] => [.wasmi32]) { f, _, _ in
@@ -141,8 +141,8 @@ class WasmAtomicsTests: XCTestCase {
141141

142142
let module = b.buildWasmModule {
143143
wasmModule in
144-
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: false)
145-
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 1, isShared: true)
144+
let unsharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: false)
145+
let sharedMemory = wasmModule.addMemory(minPages: 1, maxPages: 4, isShared: true)
146146

147147
// Load operations
148148

Tests/FuzzilliTests/WasmTests.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ class WasmFoundationTests: XCTestCase {
10771077

10781078
// Test every memory testcase for both memory32 and memory64.
10791079

1080-
func importedMemoryTestCase(isMemory64: Bool) throws {
1080+
func importedMemoryTestCase(isShared: Bool, isMemory64: Bool) throws {
10811081
let runner = try GetJavaScriptExecutorOrSkipTest()
10821082
let liveTestConfig = Configuration(logLevel: .error, enableInspection: true)
10831083

@@ -1087,8 +1087,8 @@ class WasmFoundationTests: XCTestCase {
10871087

10881088
let b = fuzzer.makeBuilder()
10891089

1090-
let wasmMemory: Variable = b.createWasmMemory(minPages: 10, maxPages: 20, isMemory64: isMemory64)
1091-
XCTAssertEqual(b.type(of: wasmMemory), .wasmMemory(limits: Limits(min: 10, max: 20), isShared: false, isMemory64: isMemory64))
1090+
let wasmMemory: Variable = b.createWasmMemory(minPages: 10, maxPages: 20, isShared: isShared, isMemory64: isMemory64)
1091+
XCTAssertEqual(b.type(of: wasmMemory), .wasmMemory(limits: Limits(min: 10, max: 20), isShared: isShared, isMemory64: isMemory64))
10921092

10931093
let module = b.buildWasmModule { wasmModule in
10941094
wasmModule.addWasmFunction(with: [] => [.wasmi64]) { function, _ in
@@ -1125,14 +1125,16 @@ class WasmFoundationTests: XCTestCase {
11251125
}
11261126

11271127
func testImportedMemory32() throws {
1128-
try importedMemoryTestCase(isMemory64: false)
1128+
try importedMemoryTestCase(isShared: false, isMemory64: false)
1129+
try importedMemoryTestCase(isShared: true, isMemory64: false)
11291130
}
11301131

11311132
func testImportedMemory64() throws {
1132-
try importedMemoryTestCase(isMemory64: true)
1133+
try importedMemoryTestCase(isShared: false, isMemory64: true)
1134+
try importedMemoryTestCase(isShared: true, isMemory64: true)
11331135
}
11341136

1135-
func defineMemory(isMemory64: Bool) throws {
1137+
func defineMemory(isShared: Bool, isMemory64: Bool) throws {
11361138
let runner = try GetJavaScriptExecutorOrSkipTest()
11371139
let liveTestConfig = Configuration(logLevel: .error, enableInspection: true)
11381140

@@ -1143,7 +1145,7 @@ class WasmFoundationTests: XCTestCase {
11431145
let b = fuzzer.makeBuilder()
11441146

11451147
let module = b.buildWasmModule { wasmModule in
1146-
let memory = wasmModule.addMemory(minPages: 5, maxPages: 12, isMemory64: isMemory64)
1148+
let memory = wasmModule.addMemory(minPages: 5, maxPages: 12, isShared: isShared, isMemory64: isMemory64)
11471149
let memoryTypeInfo = b.type(of: memory).wasmMemoryType!
11481150

11491151
wasmModule.addWasmFunction(with: [] => [.wasmi32]) { function, _ in
@@ -1164,11 +1166,13 @@ class WasmFoundationTests: XCTestCase {
11641166
}
11651167

11661168
func testDefineMemory32() throws {
1167-
try defineMemory(isMemory64: false)
1169+
try defineMemory(isShared: false, isMemory64: false)
1170+
try defineMemory(isShared: true, isMemory64: false)
11681171
}
11691172

11701173
func testDefineMemory64() throws {
1171-
try defineMemory(isMemory64: true)
1174+
try defineMemory(isShared: false, isMemory64: true)
1175+
try defineMemory(isShared: true, isMemory64: true)
11721176
}
11731177

11741178
func testMemory64Index() throws{

0 commit comments

Comments
 (0)