Skip to content

Commit f931f53

Browse files
Engine API: Split const evaluation into a separate file
This is a preparation for the future removal of Runtime.swift.
1 parent b2444c9 commit f931f53

File tree

3 files changed

+81
-79
lines changed

3 files changed

+81
-79
lines changed

Sources/WasmKit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_wasmkit_library(WasmKit
1616
Execution/Instructions/Memory.swift
1717
Execution/Instructions/Misc.swift
1818
Execution/Instructions/InstructionSupport.swift
19+
Execution/ConstEvaluation.swift
1920
Execution/DispatchInstruction.swift
2021
Execution/EngineInterceptor.swift
2122
Execution/Errors.swift
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import WasmParser
2+
3+
protocol ConstEvaluationContextProtocol {
4+
func functionRef(_ index: FunctionIndex) throws -> Reference
5+
func globalValue(_ index: GlobalIndex) throws -> Value
6+
}
7+
8+
extension InternalInstance: ConstEvaluationContextProtocol {
9+
func functionRef(_ index: FunctionIndex) throws -> Reference {
10+
return try .function(from: self.functions[validating: Int(index)])
11+
}
12+
func globalValue(_ index: GlobalIndex) throws -> Value {
13+
return try self.globals[validating: Int(index)].value
14+
}
15+
}
16+
17+
struct ConstEvaluationContext: ConstEvaluationContextProtocol {
18+
let functions: ImmutableArray<InternalFunction>
19+
var globals: [Value]
20+
func functionRef(_ index: FunctionIndex) throws -> Reference {
21+
return try .function(from: self.functions[validating: Int(index)])
22+
}
23+
func globalValue(_ index: GlobalIndex) throws -> Value {
24+
guard index < globals.count else {
25+
throw GlobalEntity.createOutOfBoundsError(index: Int(index), count: globals.count)
26+
}
27+
return self.globals[Int(index)]
28+
}
29+
}
30+
31+
extension ConstExpression {
32+
func evaluate<C: ConstEvaluationContextProtocol>(context: C) throws -> Value {
33+
guard self.last == .end, self.count == 2 else {
34+
throw InstantiationError.unsupported("Expect `end` at the end of offset expression")
35+
}
36+
let constInst = self[0]
37+
switch constInst {
38+
case .i32Const(let value): return .i32(UInt32(bitPattern: value))
39+
case .i64Const(let value): return .i64(UInt64(bitPattern: value))
40+
case .f32Const(let value): return .f32(value.bitPattern)
41+
case .f64Const(let value): return .f64(value.bitPattern)
42+
case .globalGet(let globalIndex):
43+
return try context.globalValue(globalIndex)
44+
case .refNull(let type):
45+
switch type {
46+
case .externRef: return .ref(.extern(nil))
47+
case .funcRef: return .ref(.function(nil))
48+
}
49+
case .refFunc(let functionIndex):
50+
return try .ref(context.functionRef(functionIndex))
51+
default:
52+
throw InstantiationError.unsupported("illegal const expression instruction: \(constInst)")
53+
}
54+
}
55+
}
56+
57+
extension WasmParser.ElementSegment {
58+
func evaluateInits<C: ConstEvaluationContextProtocol>(context: C) throws -> [Reference] {
59+
try self.initializer.map { expression -> Reference in
60+
switch expression[0] {
61+
case let .refFunc(index):
62+
return try context.functionRef(index)
63+
case .refNull(.funcRef):
64+
return .function(nil)
65+
case .refNull(.externRef):
66+
return .extern(nil)
67+
case .globalGet(let index):
68+
let value = try context.globalValue(index)
69+
switch value {
70+
case .ref(.function(let addr)):
71+
return .function(addr)
72+
default:
73+
throw Trap._raw("Unexpected global value type for element initializer expression")
74+
}
75+
default:
76+
throw Trap._raw("Unexpected element initializer expression: \(expression)")
77+
}
78+
}
79+
}
80+
}

Sources/WasmKit/Execution/Runtime.swift

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -241,82 +241,3 @@ public struct HostModule {
241241
/// Names of functions exported by this module mapped to corresponding host functions.
242242
public var functions: [String: HostFunction]
243243
}
244-
245-
protocol ConstEvaluationContextProtocol {
246-
func functionRef(_ index: FunctionIndex) throws -> Reference
247-
func globalValue(_ index: GlobalIndex) throws -> Value
248-
}
249-
250-
extension InternalInstance: ConstEvaluationContextProtocol {
251-
func functionRef(_ index: FunctionIndex) throws -> Reference {
252-
return try .function(from: self.functions[validating: Int(index)])
253-
}
254-
func globalValue(_ index: GlobalIndex) throws -> Value {
255-
return try self.globals[validating: Int(index)].value
256-
}
257-
}
258-
259-
struct ConstEvaluationContext: ConstEvaluationContextProtocol {
260-
let functions: ImmutableArray<InternalFunction>
261-
var globals: [Value]
262-
func functionRef(_ index: FunctionIndex) throws -> Reference {
263-
return try .function(from: self.functions[validating: Int(index)])
264-
}
265-
func globalValue(_ index: GlobalIndex) throws -> Value {
266-
guard index < globals.count else {
267-
throw GlobalEntity.createOutOfBoundsError(index: Int(index), count: globals.count)
268-
}
269-
return self.globals[Int(index)]
270-
}
271-
}
272-
273-
extension ConstExpression {
274-
func evaluate<C: ConstEvaluationContextProtocol>(context: C) throws -> Value {
275-
guard self.last == .end, self.count == 2 else {
276-
throw InstantiationError.unsupported("Expect `end` at the end of offset expression")
277-
}
278-
let constInst = self[0]
279-
switch constInst {
280-
case .i32Const(let value): return .i32(UInt32(bitPattern: value))
281-
case .i64Const(let value): return .i64(UInt64(bitPattern: value))
282-
case .f32Const(let value): return .f32(value.bitPattern)
283-
case .f64Const(let value): return .f64(value.bitPattern)
284-
case .globalGet(let globalIndex):
285-
return try context.globalValue(globalIndex)
286-
case .refNull(let type):
287-
switch type {
288-
case .externRef: return .ref(.extern(nil))
289-
case .funcRef: return .ref(.function(nil))
290-
}
291-
case .refFunc(let functionIndex):
292-
return try .ref(context.functionRef(functionIndex))
293-
default:
294-
throw InstantiationError.unsupported("illegal const expression instruction: \(constInst)")
295-
}
296-
}
297-
}
298-
299-
extension WasmParser.ElementSegment {
300-
func evaluateInits<C: ConstEvaluationContextProtocol>(context: C) throws -> [Reference] {
301-
try self.initializer.map { expression -> Reference in
302-
switch expression[0] {
303-
case let .refFunc(index):
304-
return try context.functionRef(index)
305-
case .refNull(.funcRef):
306-
return .function(nil)
307-
case .refNull(.externRef):
308-
return .extern(nil)
309-
case .globalGet(let index):
310-
let value = try context.globalValue(index)
311-
switch value {
312-
case .ref(.function(let addr)):
313-
return .function(addr)
314-
default:
315-
throw Trap._raw("Unexpected global value type for element initializer expression")
316-
}
317-
default:
318-
throw Trap._raw("Unexpected element initializer expression: \(expression)")
319-
}
320-
}
321-
}
322-
}

0 commit comments

Comments
 (0)