Skip to content

Commit b32dbca

Browse files
NFC: Split the invoke method to prepare for tail-call implementation
1 parent 05a091c commit b32dbca

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed

Sources/WasmKit/Execution/Execution.swift

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ struct Execution {
8080

8181
/// Pushes a new call frame to the VM stack.
8282
@inline(__always)
83-
mutating func pushFrame(
83+
func pushFrame(
8484
iseq: InstructionSequence,
8585
function: EntityHandle<WasmFunctionEntity>,
8686
numberOfNonParameterLocals: Int,
@@ -107,7 +107,7 @@ struct Execution {
107107

108108
/// Pops the current frame from the VM stack.
109109
@inline(__always)
110-
mutating func popFrame(sp: inout Sp, pc: inout Pc, md: inout Md, ms: inout Ms) {
110+
func popFrame(sp: inout Sp, pc: inout Pc, md: inout Md, ms: inout Ms) {
111111
let oldSp = sp
112112
sp = oldSp.previousSP.unsafelyUnwrapped
113113
pc = oldSp.returnPC.unsafelyUnwrapped
@@ -507,46 +507,67 @@ extension Execution {
507507

508508
/// Returns the new program counter and stack pointer.
509509
@inline(never)
510-
mutating func invoke(
510+
func invoke(
511511
function: InternalFunction,
512512
callerInstance: InternalInstance?,
513513
spAddend: VReg,
514514
sp: Sp, pc: Pc, md: inout Md, ms: inout Ms
515515
) throws -> (Pc, Sp) {
516516
if function.isWasm {
517-
let function = function.wasm
518-
let iseq = try function.ensureCompiled(store: store)
519-
520-
let newSp = try pushFrame(
521-
iseq: iseq,
522-
function: function,
523-
numberOfNonParameterLocals: function.numberOfNonParameterLocals,
524-
sp: sp,
525-
returnPC: pc,
526-
spAddend: spAddend
527-
)
528-
Execution.CurrentMemory.mayUpdateCurrentInstance(
529-
instance: function.instance,
530-
from: callerInstance, md: &md, ms: &ms
517+
return try invokeWasmFunction(
518+
function: function.wasm, callerInstance: callerInstance,
519+
spAddend: spAddend, sp: sp, pc: pc, md: &md, ms: &ms
531520
)
532-
return (iseq.baseAddress, newSp)
533521
} else {
534-
let function = function.host
535-
let resolvedType = store.value.engine.resolveType(function.type)
536-
let layout = FrameHeaderLayout(type: resolvedType)
537-
let parameters = resolvedType.parameters.enumerated().map { (i, type) in
538-
sp[spAddend + layout.paramReg(i)].cast(to: type)
539-
}
540-
let instance = self.currentInstance(sp: sp)
541-
let caller = Caller(
542-
instanceHandle: instance,
543-
store: store.value
544-
)
545-
let results = try function.implementation(caller, Array(parameters))
546-
for (index, result) in results.enumerated() {
547-
sp[spAddend + layout.returnReg(index)] = UntypedValue(result)
548-
}
522+
try invokeHostFunction(function: function.host, sp: sp, spAddend: spAddend)
549523
return (pc, sp)
550524
}
551525
}
526+
527+
/// Executes the given WebAssembly function.
528+
@inline(__always)
529+
private func invokeWasmFunction(
530+
function: EntityHandle<WasmFunctionEntity>,
531+
callerInstance: InternalInstance?,
532+
spAddend: VReg,
533+
sp: Sp, pc: Pc, md: inout Md, ms: inout Ms
534+
) throws -> (Pc, Sp) {
535+
let iseq = try function.ensureCompiled(store: store)
536+
537+
let newSp = try pushFrame(
538+
iseq: iseq,
539+
function: function,
540+
numberOfNonParameterLocals: function.numberOfNonParameterLocals,
541+
sp: sp,
542+
returnPC: pc,
543+
spAddend: spAddend
544+
)
545+
Execution.CurrentMemory.mayUpdateCurrentInstance(
546+
instance: function.instance,
547+
from: callerInstance, md: &md, ms: &ms
548+
)
549+
return (iseq.baseAddress, newSp)
550+
}
551+
552+
/// Executes the given host function.
553+
///
554+
/// Note that this function does not modify neither the positions of the
555+
/// stack pointer nor the program counter.
556+
@inline(never)
557+
private func invokeHostFunction(function: EntityHandle<HostFunctionEntity>, sp: Sp, spAddend: VReg) throws {
558+
let resolvedType = store.value.engine.resolveType(function.type)
559+
let layout = FrameHeaderLayout(type: resolvedType)
560+
let parameters = resolvedType.parameters.enumerated().map { (i, type) in
561+
sp[spAddend + layout.paramReg(i)].cast(to: type)
562+
}
563+
let instance = self.currentInstance(sp: sp)
564+
let caller = Caller(
565+
instanceHandle: instance,
566+
store: store.value
567+
)
568+
let results = try function.implementation(caller, Array(parameters))
569+
for (index, result) in results.enumerated() {
570+
sp[spAddend + layout.returnReg(index)] = UntypedValue(result)
571+
}
572+
}
552573
}

0 commit comments

Comments
 (0)