Showing the changes to libraries/script-engine/src/v8/ScriptEngineV8.cpp (1 of 10 files). Show all
Unified · Split
| @@ -113,6 +113,8 @@ ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString& · 112 unmodified lines | ||
| 113 | 113 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { |
| 114 | 114 | return nullValue(); |
| 115 | 115 | } |
| 116 | + v8::HandleScope handleScope(_v8Isolate); | |
| 117 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 116 | 118 | return nullValue(); |
| 117 | 119 | |
| 118 | 120 | //V8TODO |
| @@ -136,6 +138,8 @@ ScriptValue ScriptEngineV8::cheskScriptSyntax(ScriptProgramPointer program) { · 17 unmodified lines | ||
| 136 | 138 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { |
| 137 | 139 | return nullValue(); |
| 138 | 140 | } |
| 141 | + v8::HandleScope handleScope(_v8Isolate); | |
| 142 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 139 | 143 | ScriptSyntaxCheckResultPointer syntaxCheck = program->checkSyntax(); |
| 140 | 144 | //V8TODO |
| 141 | 145 | if (syntaxCheck->state() != ScriptSyntaxCheckResult::Valid) { |
| @@ -190,6 +194,8 @@ ScriptValue ScriptEngineV8::cloneUncaughtException(const QString& extraDetail) { · 48 unmodified lines | ||
| 190 | 194 | if (!hasUncaughtException()) { |
| 191 | 195 | return nullValue(); |
| 192 | 196 | } |
| 197 | + v8::HandleScope handleScope(_v8Isolate); | |
| 198 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 193 | 199 | return nullValue(); |
| 194 | 200 | //V8TODO |
| 195 | 201 | /* |
| @@ -284,6 +290,8 @@ bool ScriptEngineV8::maybeEmitUncaughtException(const QString& debugHint) { · 88 unmodified lines | ||
| 284 | 290 | ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8ScriptContext*, ScriptEngineV8*)> operation, |
| 285 | 291 | const V8ScriptValue& data, |
| 286 | 292 | const ValueOwnership& ownership) { |
| 293 | + v8::HandleScope handleScope(_v8Isolate); | |
| 294 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 287 | 295 | auto lambda = new Lambda(this, operation, data); |
| 288 | 296 | auto object = newQObject(lambda, ownership); |
| 289 | 297 | //V8TODO? |
| @@ -294,6 +302,7 @@ ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8Scri · 4 unmodified lines | ||
| 294 | 302 | } |
| 295 | 303 | QString Lambda::toString() const { |
| 296 | 304 | v8::HandleScope handleScope(_engine->getIsolate()); |
| 305 | + v8::Context::Scope contextScope(_engine->getContext()); | |
| 297 | 306 | v8::Local<v8::String> string; |
| 298 | 307 | QString qString(""); |
| 299 | 308 | if (_data.constGet()->ToString(_engine->getContext()).ToLocal(&string)) { |
| @@ -373,30 +382,14 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) : · 73 unmodified lines | ||
| 373 | 382 | v8::Isolate::CreateParams isolateParams; |
| 374 | 383 | isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); |
| 375 | 384 | _v8Isolate = v8::Isolate::New(isolateParams); |
| 385 | + _v8Isolate->Enter(); | |
| 376 | 386 | v8::HandleScope handleScope(_v8Isolate); |
| 377 | 387 | v8::Local<v8::Context> context = v8::Context::New(_v8Isolate); |
| 388 | + Q_ASSERT(!context.IsEmpty()); | |
| 378 | 389 | _v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context); |
| 379 | 390 | |
| 380 | 391 | registerSystemTypes(); |
| 381 | 392 | |
| 382 | − _currentThread = QThread::currentThread(); | |
| 383 | − // V8TODO: port to V8 | |
| 384 | − /* | |
| 385 | − if (_scriptManager) { | |
| 386 | − connect(this, &QScriptEngine::signalHandlerException, this, [this](const V8ScriptValue& exception) { | |
| 387 | − if (hasUncaughtException()) { | |
| 388 | − // the engine's uncaughtException() seems to produce much better stack traces here | |
| 389 | − emit _scriptManager->unhandledException(cloneUncaughtException("signalHandlerException")); | |
| 390 | − clearExceptions(); | |
| 391 | − } else { | |
| 392 | − // ... but may not always be available -- so if needed we fallback to the passed exception | |
| 393 | − V8ScriptValue thrown = makeError(exception); | |
| 394 | − emit _scriptManager->unhandledException(ScriptValue(new ScriptValueV8Wrapper(this, std::move(thrown)))); | |
| 395 | − } | |
| 396 | − }, Qt::DirectConnection); | |
| 397 | − moveToThread(scriptManager->thread()); | |
| 398 | − }*/ | |
| 399 | − | |
| 400 | 393 | // V8TODO: dispose of isolate on ScriptEngineV8 destruction |
| 401 | 394 | //v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate)); |
| 402 | 395 | //_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null))); |
| @@ -410,6 +403,25 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) : · 7 unmodified lines | ||
| 410 | 403 | |
| 411 | 404 | // V8TODO: |
| 412 | 405 | //QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND); |
| 406 | + | |
| 407 | + //_currentThread = QThread::currentThread(); | |
| 408 | + | |
| 409 | + if (_scriptManager) { | |
| 410 | + // V8TODO: port to V8 | |
| 411 | + /*connect(this, &QScriptEngine::signalHandlerException, this, [this](const V8ScriptValue& exception) { | |
| 412 | + if (hasUncaughtException()) { | |
| 413 | + // the engine's uncaughtException() seems to produce much better stack traces here | |
| 414 | + emit _scriptManager->unhandledException(cloneUncaughtException("signalHandlerException")); | |
| 415 | + clearExceptions(); | |
| 416 | + } else { | |
| 417 | + // ... but may not always be available -- so if needed we fallback to the passed exception | |
| 418 | + V8ScriptValue thrown = makeError(exception); | |
| 419 | + emit _scriptManager->unhandledException(ScriptValue(new ScriptValueV8Wrapper(this, std::move(thrown)))); | |
| 420 | + } | |
| 421 | + }, Qt::DirectConnection);*/ | |
| 422 | + //moveToThread(scriptManager->thread()); | |
| 423 | + setThread(scriptManager->thread()); | |
| 424 | + } | |
| 413 | 425 | } |
| 414 | 426 | |
| 415 | 427 | void ScriptEngineV8::registerEnum(const QString& enumName, QMetaEnum newEnum) { |
| @@ -417,6 +429,8 @@ void ScriptEngineV8::registerEnum(const QString& enumName, QMetaEnum newEnum) { · 1 unmodified line | ||
| 417 | 429 | qCCritical(scriptengine) << "registerEnum called on invalid enum with name " << enumName; |
| 418 | 430 | return; |
| 419 | 431 | } |
| 432 | + v8::HandleScope handleScope(_v8Isolate); | |
| 433 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 420 | 434 | |
| 421 | 435 | for (int i = 0; i < newEnum.keyCount(); i++) { |
| 422 | 436 | const char* keyName = newEnum.key(i); |
| @@ -426,8 +440,7 @@ void ScriptEngineV8::registerEnum(const QString& enumName, QMetaEnum newEnum) { · 3 unmodified lines | ||
| 426 | 440 | } |
| 427 | 441 | |
| 428 | 442 | void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value) { |
| 429 | − //V8TODO | |
| 430 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 443 | + if (QThread::currentThread() != thread()) { | |
| 431 | 444 | #ifdef THREAD_DEBUGGING |
| 432 | 445 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerValue() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]"; |
| 433 | 446 | #endif |
| @@ -435,8 +448,9 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value · 1 unmodified line | ||
| 435 | 448 | Q_ARG(const QString&, valueName), |
| 436 | 449 | Q_ARG(V8ScriptValue, value)); |
| 437 | 450 | return; |
| 438 | − }*/ | |
| 451 | + } | |
| 439 | 452 | v8::HandleScope handleScope(_v8Isolate); |
| 453 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 440 | 454 | QStringList pathToValue = valueName.split("."); |
| 441 | 455 | int partsToGo = pathToValue.length(); |
| 442 | 456 | v8::Local<v8::Object> partObject = _v8Context.Get(_v8Isolate)->Global(); |
| @@ -470,8 +484,7 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value · 27 unmodified lines | ||
| 470 | 484 | } |
| 471 | 485 | |
| 472 | 486 | void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) { |
| 473 | − //V8TODO | |
| 474 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 487 | + if (QThread::currentThread() != thread()) { | |
| 475 | 488 | #ifdef THREAD_DEBUGGING |
| 476 | 489 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerGlobalObject() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] name:" << name; |
| 477 | 490 | #endif |
| @@ -482,8 +495,10 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) · 4 unmodified lines | ||
| 482 | 495 | } |
| 483 | 496 | #ifdef THREAD_DEBUGGING |
| 484 | 497 | qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name; |
| 485 | −#endif*/ | |
| 498 | +#endif | |
| 486 | 499 | v8::HandleScope handleScope(_v8Isolate); |
| 500 | + Q_ASSERT(_v8Isolate->IsCurrent()); | |
| 501 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 487 | 502 | v8::Local<v8::Object> v8GlobalObject = getContext()->Global(); |
| 488 | 503 | v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked(); |
| 489 | 504 | |
| @@ -499,22 +514,23 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) · 9 unmodified lines | ||
| 499 | 514 | } |
| 500 | 515 | |
| 501 | 516 | void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) { |
| 502 | − //V8TODO | |
| 503 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 517 | + if (QThread::currentThread() != thread()) { | |
| 504 | 518 | #ifdef THREAD_DEBUGGING |
| 505 | 519 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerFunction() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] name:" << name; |
| 506 | 520 | #endif |
| 507 | 521 | QMetaObject::invokeMethod(this, "registerFunction", |
| 508 | 522 | Q_ARG(const QString&, name), |
| 509 | − Q_ARG(QScriptEngine::FunctionSignature, functionSignature), | |
| 523 | + Q_ARG(ScriptEngine::FunctionSignature, functionSignature), | |
| 510 | 524 | Q_ARG(int, numArguments)); |
| 511 | 525 | return; |
| 512 | 526 | } |
| 513 | 527 | #ifdef THREAD_DEBUGGING |
| 514 | 528 | qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name; |
| 515 | −#endif*/ | |
| 529 | +#endif | |
| 516 | 530 | |
| 517 | 531 | //auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet(); |
| 532 | + v8::HandleScope handleScope(_v8Isolate); | |
| 533 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 518 | 534 | auto scriptFun = newFunction(functionSignature, numArguments); |
| 519 | 535 | |
| 520 | 536 | //getContext()->Global().Set(); |
| @@ -522,21 +538,22 @@ void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::Functio · 1 unmodified line | ||
| 522 | 538 | } |
| 523 | 539 | |
| 524 | 540 | void ScriptEngineV8::registerFunction(const QString& parent, const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) { |
| 525 | − //V8TODO | |
| 526 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 541 | + if (QThread::currentThread() != thread()) { | |
| 527 | 542 | #ifdef THREAD_DEBUGGING |
| 528 | 543 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerFunction() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] parent:" << parent << "name:" << name; |
| 529 | 544 | #endif |
| 530 | 545 | QMetaObject::invokeMethod(this, "registerFunction", |
| 531 | 546 | Q_ARG(const QString&, name), |
| 532 | − Q_ARG(QScriptEngine::FunctionSignature, functionSignature), | |
| 547 | + Q_ARG(ScriptEngine::FunctionSignature, functionSignature), | |
| 533 | 548 | Q_ARG(int, numArguments)); |
| 534 | 549 | return; |
| 535 | 550 | } |
| 536 | 551 | #ifdef THREAD_DEBUGGING |
| 537 | 552 | qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name; |
| 538 | −#endif*/ | |
| 553 | +#endif | |
| 539 | 554 | |
| 555 | + v8::HandleScope handleScope(_v8Isolate); | |
| 556 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 540 | 557 | ScriptValue object = globalObject().property(parent); |
| 541 | 558 | if (object.isValid()) { |
| 542 | 559 | ScriptValue scriptFun = ScriptEngine::newFunction(functionSignature, numArguments); |
| @@ -546,8 +563,7 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name · 3 unmodified lines | ||
| 546 | 563 | |
| 547 | 564 | void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::FunctionSignature getter, |
| 548 | 565 | ScriptEngine::FunctionSignature setter, const QString& parent) { |
| 549 | − //V8TODO | |
| 550 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 566 | + if (QThread::currentThread() != thread()) { | |
| 551 | 567 | #ifdef THREAD_DEBUGGING |
| 552 | 568 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerGetterSetter() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| 553 | 569 | " name:" << name << "parent:" << parent; |
| @@ -561,7 +577,10 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun · 7 unmodified lines | ||
| 561 | 577 | } |
| 562 | 578 | #ifdef THREAD_DEBUGGING |
| 563 | 579 | qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent; |
| 564 | −#endif*/ | |
| 580 | +#endif | |
| 581 | + | |
| 582 | + v8::HandleScope handleScope(_v8Isolate); | |
| 583 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 565 | 584 | |
| 566 | 585 | ScriptValue setterFunction = newFunction(setter, 1); |
| 567 | 586 | ScriptValue getterFunction = newFunction(getter); |
| @@ -585,6 +604,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 17 unmodified lines | ||
| 585 | 604 | return nullValue(); |
| 586 | 605 | } |
| 587 | 606 | v8::HandleScope handleScope(_v8Isolate); |
| 607 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 588 | 608 | ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program); |
| 589 | 609 | if (unwrappedProgram == nullptr) { |
| 590 | 610 | return nullValue(); |
| @@ -684,7 +704,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 93 unmodified lines | ||
| 684 | 704 | setGlobalObject(oldGlobal); |
| 685 | 705 | }*/ |
| 686 | 706 | |
| 687 | − _v8Context.Get(_v8Isolate)->Enter(); | |
| 707 | + //_v8Context.Get(_v8Isolate)->Enter(); | |
| 688 | 708 | return result; |
| 689 | 709 | } |
| 690 | 710 | |
| @@ -695,7 +715,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 4 unmodified lines | ||
| 695 | 715 | |
| 696 | 716 | //V8TODO |
| 697 | 717 | |
| 698 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 718 | + if (QThread::currentThread() != thread()) { | |
| 699 | 719 | ScriptValue result; |
| 700 | 720 | #ifdef THREAD_DEBUGGING |
| 701 | 721 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| @@ -706,10 +726,11 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 4 unmodified lines | ||
| 706 | 726 | Q_ARG(const QString&, sourceCode), |
| 707 | 727 | Q_ARG(const QString&, fileName)); |
| 708 | 728 | return result; |
| 709 | − }*/ | |
| 729 | + } | |
| 710 | 730 | // Compile and check syntax |
| 711 | 731 | // V8TODO: Could these all be replaced with checkSyntax function from wrapper? |
| 712 | 732 | v8::HandleScope handleScope(_v8Isolate); |
| 733 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 713 | 734 | v8::TryCatch tryCatch(getIsolate()); |
| 714 | 735 | v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked()); |
| 715 | 736 | v8::Local<v8::Script> script; |
| @@ -775,8 +796,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 59 unmodified lines | ||
| 775 | 796 | return undefinedValue(); // bail early |
| 776 | 797 | } |
| 777 | 798 | |
| 778 | − //V8TODO | |
| 779 | − /*if (QThread::currentThread() != QScriptEngine::thread()) { | |
| 799 | + if (QThread::currentThread() != thread()) { | |
| 780 | 800 | ScriptValue result; |
| 781 | 801 | #ifdef THREAD_DEBUGGING |
| 782 | 802 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| @@ -786,8 +806,9 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 3 unmodified lines | ||
| 786 | 806 | Q_RETURN_ARG(ScriptValue, result), |
| 787 | 807 | Q_ARG(const ScriptProgramPointer&, program)); |
| 788 | 808 | return result; |
| 789 | − }*/ | |
| 809 | + } | |
| 790 | 810 | v8::HandleScope handleScope(_v8Isolate); |
| 811 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 791 | 812 | ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program); |
| 792 | 813 | if (!unwrapped) { |
| 793 | 814 | auto err = makeError(newValue("could not unwrap program")); |
| @@ -843,6 +864,7 @@ void ScriptEngineV8::updateMemoryCost(const qint64& deltaSize) { · 49 unmodified lines | ||
| 843 | 864 | |
| 844 | 865 | ScriptValue ScriptEngineV8::globalObject() const { |
| 845 | 866 | v8::HandleScope handleScope(_v8Isolate); |
| 867 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 846 | 868 | V8ScriptValue global(_v8Isolate, getConstContext()->Global());// = QScriptEngine::globalObject(); // can't cache the value as it may change |
| 847 | 869 | return ScriptValue(new ScriptValueV8Wrapper(const_cast<ScriptEngineV8*>(this), std::move(global))); |
| 848 | 870 | } |
| @@ -852,12 +874,15 @@ ScriptManager* ScriptEngineV8::manager() const { · 3 unmodified lines | ||
| 852 | 874 | } |
| 853 | 875 | |
| 854 | 876 | ScriptValue ScriptEngineV8::newArray(uint length) { |
| 877 | + v8::HandleScope handleScope(_v8Isolate); | |
| 878 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 855 | 879 | V8ScriptValue result(_v8Isolate, v8::Array::New(_v8Isolate, static_cast<int>(length))); |
| 856 | 880 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 857 | 881 | } |
| 858 | 882 | |
| 859 | 883 | ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) { |
| 860 | 884 | v8::HandleScope handleScope(_v8Isolate); |
| 885 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 861 | 886 | //V8TODO: this will leak memory |
| 862 | 887 | std::shared_ptr<v8::BackingStore> backingStore(v8::ArrayBuffer::NewBackingStore(_v8Isolate, message.size())); |
| 863 | 888 | std::memcpy(backingStore.get()->Data(), message.constData(), message.size()); |
| @@ -873,12 +898,16 @@ ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) { · 9 unmodified lines | ||
| 873 | 898 | } |
| 874 | 899 | |
| 875 | 900 | ScriptValue ScriptEngineV8::newObject() { |
| 901 | + v8::HandleScope handleScope(_v8Isolate); | |
| 902 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 876 | 903 | V8ScriptValue result(_v8Isolate, v8::Object::New(_v8Isolate)); |
| 877 | 904 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 878 | 905 | } |
| 879 | 906 | |
| 880 | 907 | ScriptValue ScriptEngineV8::newMethod(QObject* object, V8ScriptValue lifetime, |
| 881 | 908 | const QList<QMetaMethod>& metas, int numMaxParams) { |
| 909 | + v8::HandleScope handleScope(_v8Isolate); | |
| 910 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 882 | 911 | V8ScriptValue result(ScriptMethodV8Proxy::newMethod(this, object, lifetime, metas, numMaxParams)); |
| 883 | 912 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 884 | 913 | } |
| @@ -893,33 +922,43 @@ ScriptProgramPointer ScriptEngineV8::newProgram(const QString& sourceCode, const · 8 unmodified lines | ||
| 893 | 922 | ScriptValue ScriptEngineV8::newQObject(QObject* object, |
| 894 | 923 | ScriptEngine::ValueOwnership ownership, |
| 895 | 924 | const ScriptEngine::QObjectWrapOptions& options) { |
| 925 | + v8::HandleScope handleScope(_v8Isolate); | |
| 926 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 896 | 927 | V8ScriptValue result = ScriptObjectV8Proxy::newQObject(this, object, ownership, options); |
| 897 | 928 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 898 | 929 | } |
| 899 | 930 | |
| 900 | 931 | ScriptValue ScriptEngineV8::newValue(bool value) { |
| 932 | + v8::HandleScope handleScope(_v8Isolate); | |
| 933 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 901 | 934 | V8ScriptValue result(_v8Isolate, v8::Boolean::New(_v8Isolate, value)); |
| 902 | 935 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 903 | 936 | } |
| 904 | 937 | |
| 905 | 938 | ScriptValue ScriptEngineV8::newValue(int value) { |
| 939 | + v8::HandleScope handleScope(_v8Isolate); | |
| 940 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 906 | 941 | V8ScriptValue result(_v8Isolate, v8::Integer::New(_v8Isolate, value)); |
| 907 | 942 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 908 | 943 | } |
| 909 | 944 | |
| 910 | 945 | ScriptValue ScriptEngineV8::newValue(uint value) { |
| 946 | + v8::HandleScope handleScope(_v8Isolate); | |
| 947 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 911 | 948 | V8ScriptValue result(_v8Isolate, v8::Uint32::New(_v8Isolate, value)); |
| 912 | 949 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 913 | 950 | } |
| 914 | 951 | |
| 915 | 952 | ScriptValue ScriptEngineV8::newValue(double value) { |
| 916 | 953 | v8::HandleScope handleScope(_v8Isolate); |
| 954 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 917 | 955 | V8ScriptValue result(_v8Isolate, v8::Number::New(_v8Isolate, value)); |
| 918 | 956 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 919 | 957 | } |
| 920 | 958 | |
| 921 | 959 | ScriptValue ScriptEngineV8::newValue(const QString& value) { |
| 922 | 960 | v8::HandleScope handleScope(_v8Isolate); |
| 961 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 923 | 962 | v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.toStdString().c_str(), v8::NewStringType::kNormal).ToLocalChecked(); |
| 924 | 963 | V8ScriptValue result(_v8Isolate, valueV8); |
| 925 | 964 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| @@ -927,6 +966,7 @@ ScriptValue ScriptEngineV8::newValue(const QString& value) { · 1 unmodified line | ||
| 927 | 966 | |
| 928 | 967 | ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) { |
| 929 | 968 | v8::HandleScope handleScope(_v8Isolate); |
| 969 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 930 | 970 | v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.latin1(), v8::NewStringType::kNormal).ToLocalChecked(); |
| 931 | 971 | V8ScriptValue result(_v8Isolate, valueV8); |
| 932 | 972 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| @@ -934,12 +974,15 @@ ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) { · 1 unmodified line | ||
| 934 | 974 | |
| 935 | 975 | ScriptValue ScriptEngineV8::newValue(const char* value) { |
| 936 | 976 | v8::HandleScope handleScope(_v8Isolate); |
| 977 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 937 | 978 | v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value, v8::NewStringType::kNormal).ToLocalChecked(); |
| 938 | 979 | V8ScriptValue result(_v8Isolate, valueV8); |
| 939 | 980 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 940 | 981 | } |
| 941 | 982 | |
| 942 | 983 | ScriptValue ScriptEngineV8::newVariant(const QVariant& value) { |
| 984 | + v8::HandleScope handleScope(_v8Isolate); | |
| 985 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 943 | 986 | V8ScriptValue result = castVariantToValue(value); |
| 944 | 987 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result))); |
| 945 | 988 | } |
| @@ -1005,12 +1048,14 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 59 unmodified lines | ||
| 1005 | 1048 | //V8TODO: is using GetCurrentContext ok, or context wrapper needs to be added? |
| 1006 | 1049 | v8::HandleScope handleScope(info.GetIsolate()); |
| 1007 | 1050 | auto context = info.GetIsolate()->GetCurrentContext(); |
| 1051 | + v8::Context::Scope contextScope(context); | |
| 1052 | + auto object = v8::Local<v8::Object>::Cast(info.Data()); | |
| 1008 | 1053 | auto function = reinterpret_cast<ScriptEngine::FunctionSignature> |
| 1009 | − (info.Data()->ToObject(context).ToLocalChecked()->GetAlignedPointerFromInternalField(0)); | |
| 1054 | + (object->GetAlignedPointerFromInternalField(0)); | |
| 1010 | 1055 | ScriptContext *scriptContext = reinterpret_cast<ScriptContext*> |
| 1011 | − (info.Data()->ToObject(context).ToLocalChecked()->GetAlignedPointerFromInternalField(1));; | |
| 1056 | + (object->GetAlignedPointerFromInternalField(1));; | |
| 1012 | 1057 | ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*> |
| 1013 | − (info.Data()->ToObject(context).ToLocalChecked()->GetAlignedPointerFromInternalField(2));; | |
| 1058 | + (object->GetAlignedPointerFromInternalField(2));; | |
| 1014 | 1059 | ScriptValue result = function(scriptContext, scriptEngine); |
| 1015 | 1060 | ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result); |
| 1016 | 1061 | info.GetReturnValue().Set(unwrapped->toV8Value().constGet()); |
| @@ -1019,6 +1064,7 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 2 unmodified lines | ||
| 1019 | 1064 | //auto functionData = v8::Object::New(_v8Isolate); |
| 1020 | 1065 | //functionData->setIn |
| 1021 | 1066 | v8::HandleScope handleScope(_v8Isolate); |
| 1067 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 1022 | 1068 | auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate); |
| 1023 | 1069 | functionDataTemplate->SetInternalFieldCount(3); |
| 1024 | 1070 | auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked(); |
| @@ -1044,6 +1090,7 @@ void ScriptEngineV8::setObjectName(const QString& name) { · 19 unmodified lines | ||
| 1044 | 1090 | //V8TODO |
| 1045 | 1091 | bool ScriptEngineV8::setProperty(const char* name, const QVariant& value) { |
| 1046 | 1092 | v8::HandleScope handleScope(_v8Isolate); |
| 1093 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 1047 | 1094 | v8::Local<v8::Object> global = getContext()->Global(); |
| 1048 | 1095 | auto v8Name = v8::String::NewFromUtf8(getIsolate(), name).ToLocalChecked(); |
| 1049 | 1096 | V8ScriptValue v8Value = castVariantToValue(value); |
| @@ -1056,13 +1103,23 @@ void ScriptEngineV8::setProcessEventsInterval(int interval) { · 6 unmodified lines | ||
| 1056 | 1103 | } |
| 1057 | 1104 | |
| 1058 | 1105 | QThread* ScriptEngineV8::thread() const { |
| 1059 | − return _currentThread; | |
| 1106 | + return QObject::thread(); | |
| 1060 | 1107 | } |
| 1061 | 1108 | |
| 1062 | 1109 | void ScriptEngineV8::setThread(QThread* thread) { |
| 1110 | + qDebug() << "Moved script engine " << objectName() << " to different thread"; | |
| 1111 | + _v8Isolate->Exit(); | |
| 1063 | 1112 | moveToThread(thread); |
| 1113 | + QMetaObject::invokeMethod(this, "enterIsolateOnThisThread"); | |
| 1114 | +} | |
| 1115 | + | |
| 1116 | +void ScriptEngineV8::enterIsolateOnThisThread() { | |
| 1117 | + Q_ASSERT(thread() == QThread::currentThread()); | |
| 1118 | + _v8Isolate->Enter(); | |
| 1119 | + qDebug() << "Script engine " << objectName() << " entered isolate on a new thread"; | |
| 1064 | 1120 | } |
| 1065 | 1121 | |
| 1122 | + | |
| 1066 | 1123 | ScriptValue ScriptEngineV8::uncaughtException() const { |
| 1067 | 1124 | //V8TODO |
| 1068 | 1125 | //V8ScriptValue result = QScriptEngine::uncaughtException(); |
| @@ -1088,12 +1145,16 @@ bool ScriptEngineV8::raiseException(const ScriptValue& exception) { · 19 unmodified lines | ||
| 1088 | 1145 | } |
| 1089 | 1146 | |
| 1090 | 1147 | ScriptValue ScriptEngineV8::create(int type, const void* ptr) { |
| 1148 | + v8::HandleScope handleScope(_v8Isolate); | |
| 1149 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 1091 | 1150 | QVariant variant(type, ptr); |
| 1092 | 1151 | V8ScriptValue scriptValue = castVariantToValue(variant); |
| 1093 | 1152 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(scriptValue))); |
| 1094 | 1153 | } |
| 1095 | 1154 | |
| 1096 | 1155 | QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) { |
| 1156 | + v8::HandleScope handleScope(_v8Isolate); | |
| 1157 | + v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 1097 | 1158 | ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(value); |
| 1098 | 1159 | if (unwrapped == nullptr) { |
| 1099 | 1160 | return QVariant(); |