Skip to content

Commit ee68ab0

Browse files
Merge pull request #9 from swiftwasm/katei/fix-release
Fix release mode bug and improve performance
2 parents 673b0fa + 9ca100e commit ee68ab0

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

Sources/WasmTransformer/BinaryFormat.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum ConstOpcode: UInt8 {
4242
case f64Const = 0x44
4343
}
4444

45+
let END_INST_OPCODE: UInt8 = 0x0B
4546
enum Opcode: Equatable {
4647
case call(UInt32)
4748
case end
@@ -53,7 +54,7 @@ enum Opcode: Equatable {
5354
switch self {
5455
case let .call(funcIndex):
5556
return [0x10] + encodeULEB128(funcIndex)
56-
case .end: return [0x0B]
57+
case .end: return [END_INST_OPCODE]
5758
case let .localGet(localIndex):
5859
return [0x20] + encodeULEB128(localIndex)
5960
case .i32WrapI64: return [0xA7]

Sources/WasmTransformer/I64Transformer.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ public struct I64ImportTransformer {
114114
func scan(typeSection: inout TypeSection, from input: inout InputByteStream) throws {
115115
let count = input.readVarUInt32()
116116
for _ in 0 ..< count {
117-
assert(input.readUInt8() == 0x60)
117+
let header = input.readUInt8()
118+
assert(header == 0x60)
118119
let (params, paramsHasI64) = try input.readResultTypes()
119120
let (results, resultsHasI64) = try input.readResultTypes()
120121
let hasI64 = paramsHasI64 || resultsHasI64
@@ -191,18 +192,21 @@ func transformCodeSection(input: inout InputByteStream, writer: OutputWriter,
191192
bodyBuffer.append(contentsOf: $0)
192193
})
193194

195+
var nonCallInstStart = input.offset
194196
while input.offset < bodyEnd {
195-
let opcode = try input.readOpcode()
196-
guard case let .call(funcIndex) = opcode,
197+
guard let (funcIndex, instSize) = try input.readCallInst(),
197198
let (_, trampolineIndex) = trampolines.trampoline(byBaseFuncIndex: Int(funcIndex))
198199
else {
199-
bodyBuffer.append(contentsOf: opcode.serialize())
200200
continue
201201
}
202+
let nonCallInstEnd = input.offset - instSize
203+
bodyBuffer.append(contentsOf: input.bytes[nonCallInstStart..<nonCallInstEnd])
204+
nonCallInstStart = input.offset
202205
let newTargetIndex = originalFuncCount + trampolineIndex
203206
let callInst = Opcode.call(UInt32(newTargetIndex))
204207
bodyBuffer.append(contentsOf: callInst.serialize())
205208
}
209+
bodyBuffer.append(contentsOf: input.bytes[nonCallInstStart..<input.offset])
206210
let newSize = bodyBuffer.count
207211
try writer.writeBytes(encodeULEB128(UInt32(newSize)))
208212
try writer.writeBytes(bodyBuffer)

Sources/WasmTransformer/InputStream.swift

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ public struct InputByteStream {
114114
case .f32Const, .f64Const, .i64Const:
115115
throw Error.expectI32Const(constOp)
116116
}
117-
let opcode = try readOpcode()
118-
guard opcode == .end else {
117+
let opcode = readUInt8()
118+
guard opcode == END_INST_OPCODE else {
119119
throw Error.expectEnd
120120
}
121121
try consumer?(bytes[start ..< offset])
@@ -159,22 +159,20 @@ public struct InputByteStream {
159159
_ = readVarUInt32()
160160
}
161161

162-
mutating func readOpcode() throws -> Opcode {
163-
let start = offset
162+
mutating func readCallInst() throws -> (funcIndex: UInt32, instSize: Int)? {
164163
let rawCode = readUInt8()
165-
var code: Opcode?
166164
switch rawCode {
167165
// https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions
168166
case 0x00, 0x01: break
169167
case 0x02, 0x03, 0x04: consumeBlockType()
170-
case 0x05: break
171-
case 0x0B: code = .end
168+
case 0x05, 0x0B: break
172169
case 0x0C, 0x0D: _ = readVarUInt32() // label index
173170
case 0x0E: consumeBrTable()
174171
case 0x0F: break
175172
case 0x10:
176-
let funcIndex = readVarUInt32()
177-
code = .call(funcIndex)
173+
let (funcIndex, advanced) = decodeULEB128(bytes[offset...], UInt32.self)
174+
offset += advanced
175+
return (funcIndex, 1 + advanced)
178176
case 0x11:
179177
_ = readVarUInt32() // type index
180178
_ = readUInt8() // 0x00
@@ -183,8 +181,7 @@ public struct InputByteStream {
183181
case 0x1A, 0x1B: break
184182

185183
// https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions
186-
case 0x20: code = .localGet(readVarUInt32())
187-
case 0x21 ... 0x24: _ = readVarUInt32() // local index
184+
case 0x20 ... 0x24: _ = readVarUInt32() // local index
188185

189186
// https://webassembly.github.io/spec/core/binary/instructions.html#memory-instructions
190187
case 0x28 ... 0x3E: consumeMemoryArg()
@@ -195,17 +192,11 @@ public struct InputByteStream {
195192
case 0x42: consumeULEB128(UInt64.self)
196193
case 0x43: _ = read(4)
197194
case 0x44: _ = read(8)
198-
case 0x45 ... 0xA6: break
199-
case 0xA7: code = .i32WrapI64
200-
case 0xA8 ... 0xC4: break
195+
case 0x45 ... 0xC4: break
201196
case 0xFC: _ = readVarUInt32()
202197
default:
203198
throw Error.unexpectedOpcode(rawCode)
204199
}
205-
if let code = code {
206-
return code
207-
} else {
208-
return .unknown(Array(bytes[start ..< offset]))
209-
}
200+
return nil
210201
}
211202
}

0 commit comments

Comments
 (0)