(func: Function)
| 2128 | } |
| 2129 | |
| 2130 | private wrapJSFuncAsSafeCallType(func: Function): ctypes.FTVMFFIWasmSafeCallType { |
| 2131 | const lib = this.lib; |
| 2132 | return ( |
| 2133 | self: Pointer, |
| 2134 | packedArgs: Pointer, |
| 2135 | numArgs: number, |
| 2136 | ret: Pointer |
| 2137 | ): number => { |
| 2138 | const jsArgs = []; |
| 2139 | // use scope to track js values. |
| 2140 | this.ctx.beginScope(); |
| 2141 | for (let i = 0; i < numArgs; ++i) { |
| 2142 | const argPtr = packedArgs + i * SizeOf.TVMFFIAny; |
| 2143 | const typeIndex = lib.memory.loadI32(argPtr); |
| 2144 | |
| 2145 | if (typeIndex >= TypeIndex.kTVMFFIRawStr) { |
| 2146 | // NOTE: the following code have limitations in asyncify mode. |
| 2147 | // The reason is that the TVMFFIAnyViewToOwnedAny will simply |
| 2148 | // get skipped during the rewinding process, causing memory failure |
| 2149 | if (!this.asyncifyHandler.isNormalStackState()) { |
| 2150 | throw Error("Cannot handle str/object argument callback in asyncify mode"); |
| 2151 | } |
| 2152 | lib.checkCall( |
| 2153 | (lib.exports.TVMFFIAnyViewToOwnedAny as ctypes.FTVMFFIAnyViewToOwnedAny)( |
| 2154 | argPtr, |
| 2155 | argPtr |
| 2156 | ) |
| 2157 | ); |
| 2158 | } |
| 2159 | jsArgs.push(this.retValueToJS(argPtr, true)); |
| 2160 | } |
| 2161 | |
| 2162 | let rv: any; |
| 2163 | try { |
| 2164 | rv = func(...jsArgs); |
| 2165 | } catch (error) { |
| 2166 | // error handling |
| 2167 | // store error via SetLastError |
| 2168 | this.ctx.endScope(); |
| 2169 | const errKind = "JSCallbackError" |
| 2170 | const errMsg = error.message; |
| 2171 | const stack = lib.getOrAllocCallStack(); |
| 2172 | const errKindOffset = stack.allocRawBytes(errKind.length + 1); |
| 2173 | stack.storeRawBytes(errKindOffset, StringToUint8Array(errKind)); |
| 2174 | const errMsgOffset = stack.allocRawBytes(errMsg.length + 1); |
| 2175 | stack.storeRawBytes(errMsgOffset, StringToUint8Array(errMsg)); |
| 2176 | stack.commitToWasmMemory(); |
| 2177 | (this.lib.exports.TVMFFIErrorSetRaisedFromCStr as ctypes.FTVMFFIErrorSetRaisedFromCStr)( |
| 2178 | stack.ptrFromOffset(errKindOffset), |
| 2179 | stack.ptrFromOffset(errMsgOffset) |
| 2180 | ); |
| 2181 | this.lib.recycleCallStack(stack); |
| 2182 | return -1; |
| 2183 | } |
| 2184 | |
| 2185 | // normal return path |
| 2186 | // recycle all js object value in function unless we want to retain them. |
| 2187 | this.ctx.endScope(); |
no test coverage detected