|
13 | 13 |
|
14 | 14 | #ifdef TARGET_WASM |
15 | 15 | void InvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *pArgs, int8_t *pRet); |
| 16 | +void InvokePInvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *stack, InterpMethodContextFrame *pFrame, int8_t *pArgs, int8_t *pRet); |
16 | 17 | void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target); |
17 | 18 | void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, int8_t *pRet, PCODE target); |
18 | 19 | #else |
@@ -101,6 +102,39 @@ void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, in |
101 | 102 | pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize); |
102 | 103 | } |
103 | 104 |
|
| 105 | +void InvokePInvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *stack, InterpMethodContextFrame *pFrame, int8_t *pArgs, int8_t *pRet) |
| 106 | +{ |
| 107 | + CONTRACTL |
| 108 | + { |
| 109 | + THROWS; |
| 110 | + MODE_ANY; |
| 111 | + PRECONDITION(CheckPointer((void*)ftn)); |
| 112 | + PRECONDITION(CheckPointer(stubHeaderTemplate)); |
| 113 | + } |
| 114 | + CONTRACTL_END |
| 115 | + |
| 116 | + // CallStubHeaders encode their destination addresses in the Routines array, so they need to be |
| 117 | + // copied to a local buffer before we can actually set their target address. |
| 118 | + size_t templateSize = stubHeaderTemplate->GetSize(); |
| 119 | + uint8_t* actualCallStub = (uint8_t*)alloca(templateSize); |
| 120 | + memcpy(actualCallStub, stubHeaderTemplate, templateSize); |
| 121 | + CallStubHeader *pHeader = (CallStubHeader*)actualCallStub; |
| 122 | + pHeader->SetTarget(ftn); // The method to call |
| 123 | + |
| 124 | + InlinedCallFrame inlinedCallFrame; |
| 125 | + inlinedCallFrame.m_pCallerReturnAddress = (TADDR)pFrame->ip; |
| 126 | + inlinedCallFrame.m_pCallSiteSP = pFrame; |
| 127 | + inlinedCallFrame.m_pCalleeSavedFP = (TADDR)stack; |
| 128 | + inlinedCallFrame.m_pThread = GetThread(); |
| 129 | + inlinedCallFrame.m_Datum = NULL; |
| 130 | + inlinedCallFrame.Push(); |
| 131 | + { |
| 132 | + GCX_PREEMP(); |
| 133 | + pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize); |
| 134 | + } |
| 135 | + inlinedCallFrame.Pop(); |
| 136 | +} |
| 137 | + |
104 | 138 | void InvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *pArgs, int8_t *pRet) |
105 | 139 | { |
106 | 140 | CONTRACTL |
@@ -1975,15 +2009,24 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr |
1975 | 2009 | callArgsOffset = ip[2]; |
1976 | 2010 | int32_t calliFunctionPointerVar = ip[3]; |
1977 | 2011 | int32_t calliCookie = ip[4]; |
| 2012 | + bool isPInvoke = ip[5] != 0; |
1978 | 2013 |
|
1979 | 2014 | CallStubHeader *pCallStub = (CallStubHeader*)pMethod->pDataItems[calliCookie]; |
1980 | | - ip += 5; |
| 2015 | + ip += 6; |
1981 | 2016 |
|
1982 | 2017 | // Save current execution state for when we return from called method |
1983 | 2018 | pFrame->ip = ip; |
1984 | 2019 |
|
1985 | 2020 | // Interpreter-FIXME: isTailcall |
1986 | | - InvokeCalliStub(LOCAL_VAR(calliFunctionPointerVar, PCODE), pCallStub, stack + callArgsOffset, stack + returnOffset); |
| 2021 | + if (isPInvoke) |
| 2022 | + { |
| 2023 | + InvokePInvokeCalliStub(LOCAL_VAR(calliFunctionPointerVar, PCODE), pCallStub, stack, pFrame, stack + callArgsOffset, stack + returnOffset); |
| 2024 | + } |
| 2025 | + else |
| 2026 | + { |
| 2027 | + InvokeCalliStub(LOCAL_VAR(calliFunctionPointerVar, PCODE), pCallStub, stack + callArgsOffset, stack + returnOffset); |
| 2028 | + } |
| 2029 | + |
1987 | 2030 | break; |
1988 | 2031 | } |
1989 | 2032 |
|
|
0 commit comments