@@ -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