| 25 | } |
| 26 | |
| 27 | NativeClassFunctionData::NativeClassFunctionData(const Valdi::Ref<Valdi::JSNativeClassData>& nativeClass, |
| 28 | const Valdi::StringBox& name) |
| 29 | : nativeClass(nativeClass), |
| 30 | referenceInfo(nativeClass->makeMemberReferenceInfo(name)) {} |
| 31 | |
| 32 | static JSValue callNativeClassInstanceMember(JSContext* context, |
| 33 | JSValueConst funcObject, |
| 34 | JSValueConst thisValue, |
| 35 | int argc, |
| 36 | JSValueConst* argv, |
| 37 | int /*flags*/) { |
| 38 | auto& valdiJsContext = *getValdiJSContext(context); |
| 39 | auto* opaque = JS_GetOpaque(funcObject, getNativeClassInstanceMemberClassDef()->classID); |
| 40 | auto functionData = Valdi::unsafeBridge<NativeClassFunctionData>(opaque); |
| 41 | |
| 42 | Valdi::JSValueRef arguments[argc]; |
| 43 | for (int i = 0; i < argc; i++) { |
| 44 | arguments[i] = Valdi::JSValueRef::makeUnretained(valdiJsContext, toValdiJSValue(argv[i])); |
| 45 | } |
| 46 | |
| 47 | Valdi::JSExceptionTracker exceptionTracker(valdiJsContext); |
| 48 | Valdi::JSFunctionNativeCallContext callContext( |
| 49 | valdiJsContext, arguments, static_cast<size_t>(argc), exceptionTracker, functionData->referenceInfo); |
| 50 | callContext.setThisValue(toValdiJSValue(thisValue)); |
| 51 | |
| 52 | auto wrappedObject = getObjectWrappedObject(thisValue); |
| 53 | auto* instanceData = dynamic_cast<Valdi::JSNativeClassInstanceData*>(wrappedObject.get()); |
| 54 | if (instanceData == nullptr || instanceData->getNativeClass() != functionData->nativeClass) { |
| 55 | return JS_ThrowTypeError(context, "Native class member called with an incompatible receiver"); |
| 56 | } |
| 57 | |
| 58 | if (valdiJsContext.interruptRequested()) { |
nothing calls this directly
no test coverage detected