| 980 | } |
| 981 | |
| 982 | bool ScriptEngine::callFunction(Object *targetObj, const char *funcName, uint32_t argc, Value *args, Value *rval /* = nullptr*/) { |
| 983 | v8::HandleScope const handleScope(_isolate); |
| 984 | |
| 985 | v8::MaybeLocal<v8::String> nameValue = _getStringPool().get(_isolate, funcName); |
| 986 | |
| 987 | if (nameValue.IsEmpty()) { |
| 988 | if (rval != nullptr) { |
| 989 | rval->setUndefined(); |
| 990 | } |
| 991 | return false; |
| 992 | } |
| 993 | |
| 994 | v8::Local<v8::String> const nameValToLocal = nameValue.ToLocalChecked(); |
| 995 | v8::Local<v8::Context> const context = _isolate->GetCurrentContext(); |
| 996 | v8::Local<v8::Object> const localObj = targetObj->_obj.handle(_isolate); |
| 997 | |
| 998 | v8::MaybeLocal<v8::Value> funcVal = localObj->Get(context, nameValToLocal); |
| 999 | if (funcVal.IsEmpty()) { |
| 1000 | if (rval != nullptr) { |
| 1001 | rval->setUndefined(); |
| 1002 | } |
| 1003 | return false; |
| 1004 | } |
| 1005 | |
| 1006 | SE_ASSERT(argc < 11, "Only support argument count that less than 11"); // NOLINT |
| 1007 | ccstd::array<v8::Local<v8::Value>, 10> argv; |
| 1008 | |
| 1009 | for (size_t i = 0; i < argc; ++i) { |
| 1010 | internal::seToJsValue(_isolate, args[i], &argv[i]); |
| 1011 | } |
| 1012 | |
| 1013 | #if CC_DEBUG |
| 1014 | v8::TryCatch tryCatch(_isolate); |
| 1015 | #endif |
| 1016 | |
| 1017 | CC_ASSERT(!funcVal.IsEmpty()); |
| 1018 | if (!funcVal.ToLocalChecked()->IsFunction()) { |
| 1019 | v8::String::Utf8Value funcStr(_isolate, funcVal.ToLocalChecked()); |
| 1020 | SE_REPORT_ERROR("%s is not a function: %s", funcName, *funcStr); |
| 1021 | return false; |
| 1022 | } |
| 1023 | |
| 1024 | v8::MaybeLocal<v8::Object> funcObj = funcVal.ToLocalChecked()->ToObject(context); |
| 1025 | v8::MaybeLocal<v8::Value> result = funcObj.ToLocalChecked()->CallAsFunction(_getContext(), localObj, argc, argv.data()); |
| 1026 | |
| 1027 | #if CC_DEBUG |
| 1028 | if (tryCatch.HasCaught()) { |
| 1029 | v8::String::Utf8Value stack(_isolate, tryCatch.StackTrace(context).ToLocalChecked()); |
| 1030 | SE_REPORT_ERROR("Invoking function failed, %s", *stack); |
| 1031 | if (rval != nullptr) { |
| 1032 | rval->setUndefined(); |
| 1033 | } |
| 1034 | tryCatch.ReThrow(); |
| 1035 | return false; |
| 1036 | } |
| 1037 | #endif |
| 1038 | |
| 1039 | if (!result.IsEmpty()) { |
no test coverage detected