Showing the changes to libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp (1 of 21 files). Show all
Unified · Split
| @@ -76,7 +76,7 @@ V8ScriptValue ScriptObjectV8Proxy::newQObject(ScriptEngineV8* engine, QObject* o · 75 unmodified lines | ||
| 76 | 76 | QSharedPointer<ScriptObjectV8Proxy> proxy = lookup.value().lock(); |
| 77 | 77 | // V8TODO: is conversion to QVariant and back needed? |
| 78 | 78 | if (proxy) { |
| 79 | − return V8ScriptValue(engine->getIsolate(), proxy.get()->toV8Value()); | |
| 79 | + return V8ScriptValue(engine, proxy.get()->toV8Value()); | |
| 80 | 80 | } |
| 81 | 81 | //if (proxy) return engine->newObject(proxy.get(), engine->newVariant(QVariant::fromValue(proxy)));; |
| 82 | 82 | } |
| @@ -111,7 +111,7 @@ V8ScriptValue ScriptObjectV8Proxy::newQObject(ScriptEngineV8* engine, QObject* o · 28 unmodified lines | ||
| 111 | 111 | QSharedPointer<ScriptObjectV8Proxy> proxy = lookup.value().lock(); |
| 112 | 112 | //if (proxy) return qengine->newObject(proxy.get(), qengine->newVariant(QVariant::fromValue(proxy)));; |
| 113 | 113 | if (proxy) { |
| 114 | − return V8ScriptValue(engine->getIsolate(), proxy.get()->toV8Value()); | |
| 114 | + return V8ScriptValue(engine, proxy.get()->toV8Value()); | |
| 115 | 115 | } |
| 116 | 116 | } |
| 117 | 117 | // V8TODO add a V8 callback that removes pointer for the script engine owned ob from the map so that it gets deleted |
| @@ -133,7 +133,7 @@ V8ScriptValue ScriptObjectV8Proxy::newQObject(ScriptEngineV8* engine, QObject* o · 15 unmodified lines | ||
| 133 | 133 | }); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | − return V8ScriptValue(engine->getIsolate(), proxy.get()->toV8Value()); | |
| 136 | + return V8ScriptValue(engine, proxy.get()->toV8Value()); | |
| 137 | 137 | //return qengine->newObject(proxy.get(), qengine->newVariant(QVariant::fromValue(proxy))); |
| 138 | 138 | } |
| 139 | 139 | |
| @@ -157,6 +157,25 @@ ScriptObjectV8Proxy* ScriptObjectV8Proxy::unwrapProxy(const V8ScriptValue& val) · 17 unmodified lines | ||
| 157 | 157 | return reinterpret_cast<ScriptObjectV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1)); |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | +ScriptObjectV8Proxy* ScriptObjectV8Proxy::unwrapProxy(v8::Isolate* isolate, v8::Local<v8::Value> &value) { | |
| 161 | + //V8TODO This shouldn't cause problems but I'm not sure if it's ok | |
| 162 | + v8::HandleScope handleScope(isolate); | |
| 163 | + if (!value->IsObject()) { | |
| 164 | + //qDebug(scriptengine) << "Cannot unwrap proxy - value is not an object"; | |
| 165 | + return nullptr; | |
| 166 | + } | |
| 167 | + v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(value); | |
| 168 | + if (v8Object->InternalFieldCount() != 3) { | |
| 169 | + //qDebug(scriptengine) << "Cannot unwrap proxy - wrong number of internal fields"; | |
| 170 | + return nullptr; | |
| 171 | + } | |
| 172 | + if (v8Object->GetAlignedPointerFromInternalField(0) != internalPointsToQObjectProxy) { | |
| 173 | + qDebug(scriptengine) << "Cannot unwrap proxy - internal fields don't point to object proxy"; | |
| 174 | + return nullptr; | |
| 175 | + } | |
| 176 | + return reinterpret_cast<ScriptObjectV8Proxy*>(v8Object->GetAlignedPointerFromInternalField(1)); | |
| 177 | +} | |
| 178 | + | |
| 160 | 179 | QObject* ScriptObjectV8Proxy::unwrap(const V8ScriptValue& val) { |
| 161 | 180 | ScriptObjectV8Proxy* proxy = unwrapProxy(val); |
| 162 | 181 | return proxy ? proxy->toQObject() : nullptr; |
| @@ -209,7 +228,7 @@ void ScriptObjectV8Proxy::investigate() { · 46 unmodified lines | ||
| 209 | 228 | } |
| 210 | 229 | |
| 211 | 230 | auto v8Name = v8::String::NewFromUtf8(_engine->getIsolate(), prop.name()).ToLocalChecked(); |
| 212 | − PropertyDef& propDef = _props.insert(idx, PropertyDef(_engine->getIsolate(), v8Name)).value(); | |
| 231 | + PropertyDef& propDef = _props.insert(idx, PropertyDef(_engine, v8Name)).value(); | |
| 213 | 232 | propDef.flags = ScriptValue::Undeletable | ScriptValue::PropertyGetter | ScriptValue::PropertySetter | |
| 214 | 233 | ScriptValue::QObjectMember; |
| 215 | 234 | if (prop.isConstant()) propDef.flags |= ScriptValue::ReadOnly; |
| @@ -248,11 +267,11 @@ void ScriptObjectV8Proxy::investigate() { · 32 unmodified lines | ||
| 248 | 267 | } |
| 249 | 268 | |
| 250 | 269 | auto nameString = v8::String::NewFromUtf8(_engine->getIsolate(), szName.data(), v8::NewStringType::kNormal, szName.length()).ToLocalChecked(); |
| 251 | − V8ScriptString name(_engine->getIsolate(), nameString); | |
| 270 | + V8ScriptString name(_engine, nameString); | |
| 252 | 271 | auto nameLookup = methodNames.find(name); |
| 253 | 272 | if (isSignal) { |
| 254 | 273 | if (nameLookup == methodNames.end()) { |
| 255 | − SignalDef& signalDef = _signals.insert(idx, SignalDef(_engine->getIsolate(), name.get())).value(); | |
| 274 | + SignalDef& signalDef = _signals.insert(idx, SignalDef(_engine, name.get())).value(); | |
| 256 | 275 | signalDef.name = name; |
| 257 | 276 | signalDef.signal = method; |
| 258 | 277 | //qDebug(scriptengine) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString)); |
| @@ -280,7 +299,7 @@ void ScriptObjectV8Proxy::investigate() { · 21 unmodified lines | ||
| 280 | 299 | } |
| 281 | 300 | } |
| 282 | 301 | if (nameLookup == methodNames.end()) { |
| 283 | − MethodDef& methodDef = _methods.insert(idx, MethodDef(_engine->getIsolate(), name.get())).value(); | |
| 302 | + MethodDef& methodDef = _methods.insert(idx, MethodDef(_engine, name.get())).value(); | |
| 284 | 303 | methodDef.name = name; |
| 285 | 304 | methodDef.numMaxParms = parameterCount; |
| 286 | 305 | methodDef.methods.append(method); |
| @@ -308,7 +327,8 @@ void ScriptObjectV8Proxy::investigate() { · 21 unmodified lines | ||
| 308 | 327 | // Add all the methods objects as properties - this allows adding properties to a given method later. Is used by Script.request. |
| 309 | 328 | // V8TODO: Should these be deleted when the script-owned object is destroyed? It needs checking if script-owned objects will be garbage-collected, or will self-referencing prevent it. |
| 310 | 329 | for (auto i = _methods.begin(); i != _methods.end(); i++) { |
| 311 | − V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine->getIsolate(), v8Object), i.value().methods, i.value().numMaxParms); | |
| 330 | + V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine, v8Object), | |
| 331 | + i.value().methods, i.value().numMaxParms); | |
| 312 | 332 | if(!propertiesObject->Set(_engine->getContext(), i.value().name.constGet(), method.get()).FromMaybe(false)) { |
| 313 | 333 | Q_ASSERT(false); |
| 314 | 334 | } |
| @@ -389,13 +409,15 @@ void ScriptObjectV8Proxy::v8Get(v8::Local<v8::Name> name, const v8::PropertyCall · 74 unmodified lines | ||
| 389 | 409 | v8::HandleScope handleScope(info.GetIsolate()); |
| 390 | 410 | v8::String::Utf8Value utf8Value(info.GetIsolate(), name); |
| 391 | 411 | //qDebug(scriptengine) << "Get: " << *utf8Value; |
| 392 | − V8ScriptValue object(info.GetIsolate(), info.This()); | |
| 393 | − ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(object); | |
| 412 | + v8::Local<v8::Value> objectV8 = info.This(); | |
| 413 | + ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(info.GetIsolate(), objectV8); | |
| 394 | 414 | if (!proxy) { |
| 395 | 415 | qDebug(scriptengine) << "Proxy object not found when getting: " << *utf8Value; |
| 396 | 416 | return; |
| 397 | 417 | } |
| 398 | − V8ScriptString nameString(info.GetIsolate(), v8::Local<v8::String>::Cast(name)); | |
| 418 | + V8ScriptValue object(proxy->_engine, objectV8); | |
| 419 | + Q_ASSERT(name->IsString()); | |
| 420 | + V8ScriptString nameString(proxy->_engine, v8::Local<v8::String>::Cast(name)); | |
| 399 | 421 | uint id; |
| 400 | 422 | QueryFlags flags = proxy->queryProperty(object, nameString, HandlesReadAccess, &id); |
| 401 | 423 | if (flags) { |
| @@ -415,18 +437,20 @@ void ScriptObjectV8Proxy::v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> v · 13 unmodified lines | ||
| 415 | 437 | v8::HandleScope handleScope(info.GetIsolate()); |
| 416 | 438 | v8::String::Utf8Value utf8Value(info.GetIsolate(), name); |
| 417 | 439 | //qDebug(scriptengine) << "Set: " << *utf8Value; |
| 418 | − V8ScriptValue object(info.GetIsolate(), info.This()); | |
| 419 | − ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(object); | |
| 440 | + v8::Local<v8::Value> objectV8 = info.This(); | |
| 441 | + ScriptObjectV8Proxy *proxy = ScriptObjectV8Proxy::unwrapProxy(info.GetIsolate(), objectV8); | |
| 420 | 442 | if (!proxy) { |
| 421 | 443 | qDebug(scriptengine) << "Proxy object not found when setting: " << *utf8Value; |
| 422 | 444 | return; |
| 423 | 445 | } |
| 424 | − V8ScriptString nameString(info.GetIsolate(), v8::Local<v8::String>::Cast(name)); | |
| 446 | + V8ScriptValue object(proxy->_engine, objectV8); | |
| 447 | + Q_ASSERT(name->IsString()); | |
| 448 | + V8ScriptString nameString(proxy->_engine, v8::Local<v8::String>::Cast(name)); | |
| 425 | 449 | //V8ScriptString nameString(info.GetIsolate(), name->ToString(proxy->_engine->getContext()).ToLocalChecked()); |
| 426 | 450 | uint id; |
| 427 | 451 | QueryFlags flags = proxy->queryProperty(object, nameString, HandlesWriteAccess, &id); |
| 428 | 452 | if (flags) { |
| 429 | − proxy->setProperty(object, nameString, id, V8ScriptValue(info.GetIsolate(), value)); | |
| 453 | + proxy->setProperty(object, nameString, id, V8ScriptValue(proxy->_engine, value)); | |
| 430 | 454 | info.GetReturnValue().Set(value); |
| 431 | 455 | } else { |
| 432 | 456 | // V8TODO: Should it be v8::Object or v8::Local<v8::Object>? |
| @@ -447,7 +471,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 14 unmodified lines | ||
| 447 | 471 | QObject* qobject = _object; |
| 448 | 472 | if (!qobject) { |
| 449 | 473 | _engine->getIsolate()->ThrowError("Referencing deleted native object"); |
| 450 | − return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 474 | + return V8ScriptValue(_engine, v8::Null(_engine->getIsolate())); | |
| 451 | 475 | } |
| 452 | 476 | |
| 453 | 477 | const QMetaObject* metaObject = qobject->metaObject(); |
| @@ -456,7 +480,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 2 unmodified lines | ||
| 456 | 480 | case PROPERTY_TYPE: { |
| 457 | 481 | int propId = id & ~TYPE_MASK; |
| 458 | 482 | PropertyDefMap::const_iterator lookup = _props.find(propId); |
| 459 | − if (lookup == _props.cend()) return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 483 | + if (lookup == _props.cend()) return V8ScriptValue(_engine, v8::Null(_engine->getIsolate())); | |
| 460 | 484 | |
| 461 | 485 | QMetaProperty prop = metaObject->property(propId); |
| 462 | 486 | ScriptValue scriptThis = ScriptValue(new ScriptValueV8Wrapper(_engine, object)); |
| @@ -469,7 +493,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 6 unmodified lines | ||
| 469 | 493 | case METHOD_TYPE: { |
| 470 | 494 | int methodId = id & ~TYPE_MASK; |
| 471 | 495 | MethodDefMap::const_iterator lookup = _methods.find(methodId); |
| 472 | − if (lookup == _methods.cend()) return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 496 | + if (lookup == _methods.cend()) return V8ScriptValue(_engine, v8::Null(_engine->getIsolate())); | |
| 473 | 497 | const MethodDef& methodDef = lookup.value(); |
| 474 | 498 | for (auto iter = methodDef.methods.begin(); iter != methodDef.methods.end(); iter++ ) { |
| 475 | 499 | if((*iter).returnType() == QMetaType::UnknownType) { |
| @@ -480,7 +504,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 4 unmodified lines | ||
| 480 | 504 | v8::Local<v8::Value> property; |
| 481 | 505 | if(_v8Object.Get(_engine->getIsolate())->GetInternalField(2).As<v8::Object>()->Get(_engine->getContext(), name.constGet()).ToLocal(&property)) { |
| 482 | 506 | if (!property->IsUndefined()) { |
| 483 | − return V8ScriptValue(_engine->getIsolate(), property); | |
| 507 | + return V8ScriptValue(_engine, property); | |
| 484 | 508 | } |
| 485 | 509 | } |
| 486 | 510 | Q_ASSERT(false); |
| @@ -490,7 +514,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 3 unmodified lines | ||
| 490 | 514 | case SIGNAL_TYPE: { |
| 491 | 515 | int signalId = id & ~TYPE_MASK; |
| 492 | 516 | SignalDefMap::const_iterator defLookup = _signals.find(signalId); |
| 493 | − if (defLookup == _signals.cend()) return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 517 | + if (defLookup == _signals.cend()) return V8ScriptValue(_engine, v8::Null(_engine->getIsolate())); | |
| 494 | 518 | |
| 495 | 519 | InstanceMap::const_iterator instLookup = _signalInstances.find(signalId); |
| 496 | 520 | if (instLookup == _signalInstances.cend() || instLookup.value().isNull()) { |
| @@ -508,7 +532,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 11 unmodified lines | ||
| 508 | 532 | //return _engine->newQObject(proxy, ScriptEngine::ScriptOwnership, options); |
| 509 | 533 | } |
| 510 | 534 | } |
| 511 | − return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 535 | + return V8ScriptValue(_engine, v8::Null(_engine->getIsolate())); | |
| 512 | 536 | } |
| 513 | 537 | |
| 514 | 538 | void ScriptObjectV8Proxy::setProperty(V8ScriptValue& object, const V8ScriptString& name, uint id, const V8ScriptValue& value) { |
| @@ -562,7 +586,7 @@ V8ScriptValue ScriptVariantV8Proxy::newVariant(ScriptEngineV8* engine, const QVa · 47 unmodified lines | ||
| 562 | 586 | if (!protoProxy) { |
| 563 | 587 | Q_ASSERT(protoProxy); |
| 564 | 588 | //return engine->newVariant(variant); |
| 565 | − return V8ScriptValue(engine->getIsolate(), v8::Undefined(engine->getIsolate())); | |
| 589 | + return V8ScriptValue(engine, v8::Undefined(engine->getIsolate())); | |
| 566 | 590 | } |
| 567 | 591 | // V8TODO probably needs connection to be deleted |
| 568 | 592 | // V8TODO what to do with proto variable? |
| @@ -572,7 +596,7 @@ V8ScriptValue ScriptVariantV8Proxy::newVariant(ScriptEngineV8* engine, const QVa · 3 unmodified lines | ||
| 572 | 596 | auto variantData = variantDataTemplate->NewInstance(engine->getContext()).ToLocalChecked(); |
| 573 | 597 | variantData->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToQVariantProxy)); |
| 574 | 598 | variantData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(proxy)); |
| 575 | − return V8ScriptValue(engine->getIsolate(), variantData); | |
| 599 | + return V8ScriptValue(engine, variantData); | |
| 576 | 600 | } |
| 577 | 601 | |
| 578 | 602 | ScriptVariantV8Proxy* ScriptVariantV8Proxy::unwrapProxy(const V8ScriptValue& val) { |
| @@ -620,7 +644,7 @@ V8ScriptValue ScriptMethodV8Proxy::newMethod(ScriptEngineV8* engine, QObject* ob · 41 unmodified lines | ||
| 620 | 644 | // V8TODO it needs to be deleted somehow on object destruction |
| 621 | 645 | methodData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(new ScriptMethodV8Proxy(engine, object, lifetime, metas, numMaxParams))); |
| 622 | 646 | auto v8Function = v8::Function::New(engine->getContext(), callback, methodData, numMaxParams).ToLocalChecked(); |
| 623 | − return V8ScriptValue(engine->getIsolate(), v8Function); | |
| 647 | + return V8ScriptValue(engine, v8Function); | |
| 624 | 648 | } |
| 625 | 649 | |
| 626 | 650 | QString ScriptMethodV8Proxy::fullName() const { |
| @@ -722,11 +746,11 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume · 95 unmodified lines | ||
| 722 | 746 | Q_ASSERT(methodArgTypeId != QMetaType::UnknownType); |
| 723 | 747 | v8::Local<v8::Value> argVal = arguments[arg]; |
| 724 | 748 | if (methodArgTypeId == scriptValueTypeId) { |
| 725 | − qScriptArgLists[i].append(ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(isolate, argVal)))); | |
| 749 | + qScriptArgLists[i].append(ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine, argVal)))); | |
| 726 | 750 | qGenArgsVectors[i][arg] = Q_ARG(ScriptValue, qScriptArgLists[i].back()); |
| 727 | 751 | } else if (methodArgTypeId == QMetaType::QVariant) { |
| 728 | 752 | QVariant varArgVal; |
| 729 | − if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) { | |
| 753 | + if (!_engine->castValueToVariant(V8ScriptValue(_engine, argVal), varArgVal, methodArgTypeId)) { | |
| 730 | 754 | conversionFailures++; |
| 731 | 755 | } else { |
| 732 | 756 | qVarArgLists[i].append(varArgVal); |
| @@ -734,12 +758,12 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume · 1 unmodified line | ||
| 734 | 758 | } |
| 735 | 759 | } else { |
| 736 | 760 | QVariant varArgVal; |
| 737 | − if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) { | |
| 761 | + if (!_engine->castValueToVariant(V8ScriptValue(_engine, argVal), varArgVal, methodArgTypeId)) { | |
| 738 | 762 | conversionFailures++; |
| 739 | 763 | } else { |
| 740 | 764 | qVarArgLists[i].append(varArgVal); |
| 741 | 765 | const QVariant& converted = qVarArgLists[i].back(); |
| 742 | − conversionPenaltyScore = _engine->computeCastPenalty(V8ScriptValue(isolate, argVal), methodArgTypeId); | |
| 766 | + conversionPenaltyScore = _engine->computeCastPenalty(V8ScriptValue(_engine, argVal), methodArgTypeId); | |
| 743 | 767 | |
| 744 | 768 | // a lot of type conversion assistance thanks to https://stackoverflow.com/questions/28457819/qt-invoke-method-with-qvariant |
| 745 | 769 | // A const_cast is needed because calling data() would detach the QVariant. |
| @@ -834,9 +858,9 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume · 88 unmodified lines | ||
| 834 | 858 | v8::Local<v8::Value> argVal = arguments[arg]; |
| 835 | 859 | if (methodArgTypeId != scriptValueTypeId) { |
| 836 | 860 | QVariant varArgVal; |
| 837 | − if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) { | |
| 861 | + if (!_engine->castValueToVariant(V8ScriptValue(_engine, argVal), varArgVal, methodArgTypeId)) { | |
| 838 | 862 | QByteArray methodTypeName = QMetaType(methodArgTypeId).name(); |
| 839 | − QByteArray argTypeName = _engine->valueType(V8ScriptValue(isolate, argVal)).toLatin1(); | |
| 863 | + QByteArray argTypeName = _engine->valueType(V8ScriptValue(_engine, argVal)).toLatin1(); | |
| 840 | 864 | QString errorMessage = QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4") |
| 841 | 865 | .arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName); |
| 842 | 866 | qDebug(scriptengine) << errorMessage << "\n Backtrace:" << _engine->currentContext()->backtrace(); |
| @@ -1043,6 +1067,8 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu · 200 unmodified lines | ||
| 1043 | 1067 | v8::Locker locker(isolate); |
| 1044 | 1068 | v8::Isolate::Scope isolateScope(isolate); |
| 1045 | 1069 | v8::HandleScope handleScope(isolate); |
| 1070 | + // V8TODO: should we use function creation context, or context in which connect happened? | |
| 1071 | + | |
| 1046 | 1072 | auto context = _engine->getContext(); |
| 1047 | 1073 | v8::Context::Scope contextScope(context); |
| 1048 | 1074 | |
| @@ -1063,20 +1089,29 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu · 14 unmodified lines | ||
| 1063 | 1089 | |
| 1064 | 1090 | for (ConnectionList::iterator iter = connections.begin(); iter != connections.end(); ++iter) { |
| 1065 | 1091 | Connection& conn = *iter; |
| 1066 | − v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(conn.callback.get()); | |
| 1067 | − v8::Local<v8::Value> v8This; | |
| 1068 | − if (conn.thisValue.get()->IsObject()) { | |
| 1069 | − v8This = conn.thisValue.get(); | |
| 1070 | − } else { | |
| 1071 | − v8This = _engine->getContext()->Global(); | |
| 1072 | − } | |
| 1092 | + Q_ASSERT(!conn.callback.get().IsEmpty()); | |
| 1093 | + Q_ASSERT(!conn.callback.get()->IsUndefined()); | |
| 1094 | + Q_ASSERT(conn.callback.get()->IsFunction()); | |
| 1095 | + { | |
| 1096 | + v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(conn.callback.get()); | |
| 1097 | + auto functionContext = callback->CreationContext(); | |
| 1098 | + _engine->pushContext(functionContext); | |
| 1099 | + v8::Context::Scope functionContextScope(functionContext); | |
| 1100 | + v8::Local<v8::Value> v8This; | |
| 1101 | + if (conn.thisValue.get()->IsObject()) { | |
| 1102 | + v8This = conn.thisValue.get(); | |
| 1103 | + } else { | |
| 1104 | + v8This = _engine->getContext()->Global(); | |
| 1105 | + } | |
| 1073 | 1106 | |
| 1074 | − v8::TryCatch tryCatch(isolate); | |
| 1075 | − callback->Call(_engine->getContext(), v8This, numArgs, args); | |
| 1076 | − if (tryCatch.HasCaught()) { | |
| 1077 | − qCDebug(scriptengine) << "Signal proxy " << fullName() << " connection call failed: \"" | |
| 1078 | − << _engine->formatErrorMessageFromTryCatch(tryCatch) | |
| 1079 | − << "\nThis provided: " << conn.thisValue.get()->IsObject(); | |
| 1107 | + v8::TryCatch tryCatch(isolate); | |
| 1108 | + callback->Call(_engine->getContext(), v8This, numArgs, args); | |
| 1109 | + if (tryCatch.HasCaught()) { | |
| 1110 | + qCDebug(scriptengine) << "Signal proxy " << fullName() << " connection call failed: \"" | |
| 1111 | + << _engine->formatErrorMessageFromTryCatch(tryCatch) | |
| 1112 | + << "\nThis provided: " << conn.thisValue.get()->IsObject(); | |
| 1113 | + } | |
| 1114 | + _engine->popContext(); | |
| 1080 | 1115 | } |
| 1081 | 1116 | } |
| 1082 | 1117 | |
| @@ -1125,8 +1160,8 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) { · 42 unmodified lines | ||
| 1125 | 1160 | //v8::HandleScope handleScope(isolate); |
| 1126 | 1161 | |
| 1127 | 1162 | // untangle the arguments |
| 1128 | − V8ScriptValue callback(isolate, v8::Null(isolate)); | |
| 1129 | − V8ScriptValue callbackThis(isolate, v8::Null(isolate)); | |
| 1163 | + V8ScriptValue callback(_engine, v8::Null(isolate)); | |
| 1164 | + V8ScriptValue callbackThis(_engine, v8::Null(isolate)); | |
| 1130 | 1165 | if (arg1.isFunction()) { |
| 1131 | 1166 | auto unwrappedArg0 = ScriptValueV8Wrapper::unwrap(arg0); |
| 1132 | 1167 | auto unwrappedArg1 = ScriptValueV8Wrapper::unwrap(arg1); |
| @@ -1158,6 +1193,9 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) { · 25 unmodified lines | ||
| 1158 | 1193 | } |
| 1159 | 1194 | |
| 1160 | 1195 | // add a reference to ourselves to the destination callback |
| 1196 | + Q_ASSERT(!callback.get().IsEmpty()); | |
| 1197 | + Q_ASSERT(!callback.get()->IsUndefined()); | |
| 1198 | + Q_ASSERT(callback.get()->IsFunction()); | |
| 1161 | 1199 | v8::Local<v8::Function> destFunction = v8::Local<v8::Function>::Cast(callback.get()); |
| 1162 | 1200 | v8::Local<v8::String> destDataName = v8::String::NewFromUtf8(isolate, "__data__").ToLocalChecked(); |
| 1163 | 1201 | v8::Local<v8::Value> destData; |
| @@ -1166,7 +1204,10 @@ void ScriptSignalV8Proxy::connect(ScriptValue arg0, ScriptValue arg1) { · 2 unmodified lines | ||
| 1166 | 1204 | //Q_ASSERT(destFunction->InternalFieldCount() == 4); |
| 1167 | 1205 | //Q_ASSERT(destData.get()->IsArray()); |
| 1168 | 1206 | //v8::Local<v8::Value> destData = destFunction->GetInternalField(3); |
| 1169 | − if (destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData) && destData->IsArray()) { | |
| 1207 | + if (!destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData)) { | |
| 1208 | + Q_ASSERT(false); | |
| 1209 | + } | |
| 1210 | + if (destData->IsArray()) { | |
| 1170 | 1211 | v8::Local<v8::Array> destArray = v8::Local<v8::Array>::Cast(destData); |
| 1171 | 1212 | int length = destArray->Length();//destData.property("length").toInteger(); |
| 1172 | 1213 | v8::Local<v8::Array> newArray = v8::Array::New(isolate, length + 1); |
| @@ -1232,8 +1273,8 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) { · 59 unmodified lines | ||
| 1232 | 1273 | v8::Context::Scope contextScope(_engine->getContext()); |
| 1233 | 1274 | |
| 1234 | 1275 | // untangle the arguments |
| 1235 | − V8ScriptValue callback(isolate, v8::Null(isolate)); | |
| 1236 | − V8ScriptValue callbackThis(isolate, v8::Null(isolate)); | |
| 1276 | + V8ScriptValue callback(_engine, v8::Null(isolate)); | |
| 1277 | + V8ScriptValue callbackThis(_engine, v8::Null(isolate)); | |
| 1237 | 1278 | if (arg1.isFunction()) { |
| 1238 | 1279 | auto unwrappedArg0 = ScriptValueV8Wrapper::unwrap(arg0); |
| 1239 | 1280 | auto unwrappedArg1 = ScriptValueV8Wrapper::unwrap(arg1); |
| @@ -1277,7 +1318,10 @@ void ScriptSignalV8Proxy::disconnect(ScriptValue arg0, ScriptValue arg1) { · 37 unmodified lines | ||
| 1277 | 1318 | V8ScriptValue v8ThisObject = ScriptValueV8Wrapper::fullUnwrap(_engine, thisObject()); |
| 1278 | 1319 | //V8ScriptValue destData = callback.data(); |
| 1279 | 1320 | //Q_ASSERT(destData->IsArray()); |
| 1280 | − if (destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData) && destData->IsArray()) { | |
| 1321 | + if (!destFunction->Get(destFunctionContext, destDataName).ToLocal(&destData)) { | |
| 1322 | + Q_ASSERT(false); | |
| 1323 | + } | |
| 1324 | + if (destData->IsArray()) { | |
| 1281 | 1325 | v8::Local<v8::Array> destArray = v8::Local<v8::Array>::Cast(destData); |
| 1282 | 1326 | int length = destArray->Length();//destData.property("length").toInteger(); |
| 1283 | 1327 | v8::Local<v8::Array> newArray = v8::Array::New(isolate, length - 1); |