History

Fixed evaluateInClosure and other V8 stuff

ksuprynowicz committed 3 years ago

Commit 70d4a431 parent cc20ced8 files · +378 −191Browse files

Showing the changes to libraries/script-engine/src/v8/ScriptEngineV8.cpp (1 of 8 files). Show all

Unified · Split

libraries/script-engine/src/v8/ScriptEngineV8.cpp+270−144
@@ -113,6 +113,8 @@ ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString& · 112 unmodified lines
113 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {113 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
114 return nullValue();114 return nullValue();
115 }115 }
116 v8::Locker locker(_v8Isolate);
117 v8::Isolate::Scope isolateScope(_v8Isolate);
116 v8::HandleScope handleScope(_v8Isolate);118 v8::HandleScope handleScope(_v8Isolate);
117 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));119 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
118 return nullValue();120 return nullValue();
@@ -138,6 +140,8 @@ ScriptValue ScriptEngineV8::checkScriptSyntax(ScriptProgramPointer program) { · 19 unmodified lines
138 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {140 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
139 return nullValue();141 return nullValue();
140 }142 }
143 v8::Locker locker(_v8Isolate);
144 v8::Isolate::Scope isolateScope(_v8Isolate);
141 v8::HandleScope handleScope(_v8Isolate);145 v8::HandleScope handleScope(_v8Isolate);
142 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));146 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
143 ScriptSyntaxCheckResultPointer syntaxCheck = program->checkSyntax();147 ScriptSyntaxCheckResultPointer syntaxCheck = program->checkSyntax();
@@ -194,6 +198,8 @@ ScriptValue ScriptEngineV8::cloneUncaughtException(const QString& extraDetail) { · 50 unmodified lines
194 if (!hasUncaughtException()) {198 if (!hasUncaughtException()) {
195 return nullValue();199 return nullValue();
196 }200 }
201 v8::Locker locker(_v8Isolate);
202 v8::Isolate::Scope isolateScope(_v8Isolate);
197 v8::HandleScope handleScope(_v8Isolate);203 v8::HandleScope handleScope(_v8Isolate);
198 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));204 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
199 return nullValue();205 return nullValue();
@@ -343,7 +349,8 @@ V8ScriptValue Lambda::call() { · 143 unmodified lines
343 349
344#ifdef DEBUG_JS350#ifdef DEBUG_JS
345void ScriptEngineV8::_debugDump(const QString& header, const V8ScriptValue& object, const QString& footer) {351void ScriptEngineV8::_debugDump(const QString& header, const V8ScriptValue& object, const QString& footer) {
346 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {352 // V8TODO
353 /*if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
347 return;354 return;
348 }355 }
349 if (!header.isEmpty()) {356 if (!header.isEmpty()) {
@@ -360,7 +367,7 @@ void ScriptEngineV8::_debugDump(const QString& header, const V8ScriptValue& obje · 10 unmodified lines
360 }367 }
361 if (!footer.isEmpty()) {368 if (!footer.isEmpty()) {
362 qCDebug(shared) << footer;369 qCDebug(shared) << footer;
363 }370 }*/
364}371}
365#endif372#endif
366 373
@@ -370,7 +377,7 @@ v8::Platform* ScriptEngineV8::getV8Platform() { · 3 unmodified lines
370}377}
371 378
372ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :379ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
373 _scriptManager(scriptManager), _isEvaluating(false)380 _scriptManager(scriptManager), _evaluatingCounter(0)
374 //V8TODO381 //V8TODO
375 //_arrayBufferClass(new ArrayBufferClass(this))382 //_arrayBufferClass(new ArrayBufferClass(this))
376{383{
@@ -395,7 +402,8 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) : · 18 unmodified lines
395 v8::Isolate::CreateParams isolateParams;402 v8::Isolate::CreateParams isolateParams;
396 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();403 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
397 _v8Isolate = v8::Isolate::New(isolateParams);404 _v8Isolate = v8::Isolate::New(isolateParams);
398 _v8Isolate->Enter();405 v8::Locker locker(_v8Isolate);
406 v8::Isolate::Scope isolateScope(_v8Isolate);
399 v8::HandleScope handleScope(_v8Isolate);407 v8::HandleScope handleScope(_v8Isolate);
400 v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);408 v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);
401 Q_ASSERT(!context.IsEmpty());409 Q_ASSERT(!context.IsEmpty());
@@ -447,6 +455,8 @@ void ScriptEngineV8::registerEnum(const QString& enumName, QMetaEnum newEnum) { · 45 unmodified lines
447 qCCritical(scriptengine) << "registerEnum called on invalid enum with name " << enumName;455 qCCritical(scriptengine) << "registerEnum called on invalid enum with name " << enumName;
448 return;456 return;
449 }457 }
458 v8::Locker locker(_v8Isolate);
459 v8::Isolate::Scope isolateScope(_v8Isolate);
450 v8::HandleScope handleScope(_v8Isolate);460 v8::HandleScope handleScope(_v8Isolate);
451 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));461 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
452 462
@@ -467,6 +477,8 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value · 14 unmodified lines
467 Q_ARG(V8ScriptValue, value));477 Q_ARG(V8ScriptValue, value));
468 return;478 return;
469 }479 }
480 v8::Locker locker(_v8Isolate);
481 v8::Isolate::Scope isolateScope(_v8Isolate);
470 v8::HandleScope handleScope(_v8Isolate);482 v8::HandleScope handleScope(_v8Isolate);
471 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));483 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
472 QStringList pathToValue = valueName.split(".");484 QStringList pathToValue = valueName.split(".");
@@ -514,34 +526,36 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) · 41 unmodified lines
514#ifdef THREAD_DEBUGGING526#ifdef THREAD_DEBUGGING
515 qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name;527 qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name;
516#endif528#endif
517 bool is_isolate_exit_needed = false;529 /*bool is_isolate_exit_needed = false;
518 if(!_v8Isolate->IsCurrent() && !_v8Locker) {530 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
519 // V8TODO: Theoretically only script thread should access this, so it should be safe531 // V8TODO: Theoretically only script thread should access this, so it should be safe
520 _v8Locker.reset(new v8::Locker(_v8Isolate));532 _v8Locker.reset(new v8::Locker(_v8Isolate));
521 _v8Isolate->Enter();533 _v8Isolate->Enter();
522 is_isolate_exit_needed = true;534 is_isolate_exit_needed = true;
523 }535 }*/
524 {536 //{
525 v8::HandleScope handleScope(_v8Isolate);537 v8::Locker locker(_v8Isolate);
526 Q_ASSERT(_v8Isolate->IsCurrent());538 v8::Isolate::Scope isolateScope(_v8Isolate);
527 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));539 v8::HandleScope handleScope(_v8Isolate);
528 v8::Local<v8::Object> v8GlobalObject = getContext()->Global();540 Q_ASSERT(_v8Isolate->IsCurrent());
529 v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();541 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
530 542 v8::Local<v8::Object> v8GlobalObject = getContext()->Global();
531 // V8TODO: Is IsEmpty check enough or IsValid is needed too?543 v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
532 if (!v8GlobalObject->Get(getContext(), v8Name).IsEmpty()) {544
533 if (object) {545 // V8TODO: Is IsEmpty check enough or IsValid is needed too?
534 V8ScriptValue value = ScriptObjectV8Proxy::newQObject(this, object, ScriptEngine::QtOwnership);546 if (!v8GlobalObject->Get(getContext(), v8Name).IsEmpty()) {
535 v8GlobalObject->Set(getContext(), v8Name, value.get());547 if (object) {
536 } else {548 V8ScriptValue value = ScriptObjectV8Proxy::newQObject(this, object, ScriptEngine::QtOwnership);
537 v8GlobalObject->Set(getContext(), v8Name, v8::Null(_v8Isolate));549 v8GlobalObject->Set(getContext(), v8Name, value.get());
538 }550 } else {
551 v8GlobalObject->Set(getContext(), v8Name, v8::Null(_v8Isolate));
539 }552 }
540 }553 }
541 if (is_isolate_exit_needed) {554 //}
555 /*if (is_isolate_exit_needed) {
542 _v8Isolate->Exit();556 _v8Isolate->Exit();
543 _v8Locker.reset(nullptr);557 _v8Locker.reset(nullptr);
544 }558 }*/
545}559}
546 560
547void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {561void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
@@ -561,26 +575,28 @@ void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::Functio · 13 unmodified lines
561 qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name;575 qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name;
562#endif576#endif
563 577
564 bool is_isolate_exit_needed = false;578 /*bool is_isolate_exit_needed = false;
565 if(!_v8Isolate->IsCurrent() && !_v8Locker) {579 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
566 // V8TODO: Theoretically only script thread should access this, so it should be safe580 // V8TODO: Theoretically only script thread should access this, so it should be safe
567 _v8Locker.reset(new v8::Locker(_v8Isolate));581 _v8Locker.reset(new v8::Locker(_v8Isolate));
568 _v8Isolate->Enter();582 _v8Isolate->Enter();
569 is_isolate_exit_needed = true;583 is_isolate_exit_needed = true;
570 }584 }
571 {585 {*/
572 //auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet();586 //auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet();
573 v8::HandleScope handleScope(_v8Isolate);587 v8::Locker locker(_v8Isolate);
574 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));588 v8::Isolate::Scope isolateScope(_v8Isolate);
575 auto scriptFun = newFunction(functionSignature, numArguments);589 v8::HandleScope handleScope(_v8Isolate);
590 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
591 auto scriptFun = newFunction(functionSignature, numArguments);
576 592
577 //getContext()->Global().Set();593 //getContext()->Global().Set();
578 globalObject().setProperty(name, scriptFun);594 globalObject().setProperty(name, scriptFun);
579 }595 /*}
580 if (is_isolate_exit_needed) {596 if (is_isolate_exit_needed) {
581 _v8Isolate->Exit();597 _v8Isolate->Exit();
582 _v8Locker.reset(nullptr);598 _v8Locker.reset(nullptr);
583 }599 }*/
584}600}
585 601
586void ScriptEngineV8::registerFunction(const QString& parent, const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {602void ScriptEngineV8::registerFunction(const QString& parent, const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
@@ -598,26 +614,28 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name · 11 unmodified lines
598 qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name;614 qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name;
599#endif615#endif
600 616
601 bool is_isolate_exit_needed = false;617 /*bool is_isolate_exit_needed = false;
602 if(!_v8Isolate->IsCurrent() && !_v8Locker) {618 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
603 // V8TODO: Theoretically only script thread should access this, so it should be safe619 // V8TODO: Theoretically only script thread should access this, so it should be safe
604 _v8Locker.reset(new v8::Locker(_v8Isolate));620 _v8Locker.reset(new v8::Locker(_v8Isolate));
605 _v8Isolate->Enter();621 _v8Isolate->Enter();
606 is_isolate_exit_needed = true;622 is_isolate_exit_needed = true;
607 }623 }
608 {624 {*/
609 v8::HandleScope handleScope(_v8Isolate);625 v8::Locker locker(_v8Isolate);
610 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));626 v8::Isolate::Scope isolateScope(_v8Isolate);
611 ScriptValue object = globalObject().property(parent);627 v8::HandleScope handleScope(_v8Isolate);
612 if (object.isValid()) {628 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
613 ScriptValue scriptFun = newFunction(functionSignature, numArguments);629 ScriptValue object = globalObject().property(parent);
614 object.setProperty(name, scriptFun);630 if (object.isValid()) {
615 }631 ScriptValue scriptFun = newFunction(functionSignature, numArguments);
632 object.setProperty(name, scriptFun);
616 }633 }
634 /*}
617 if (is_isolate_exit_needed) {635 if (is_isolate_exit_needed) {
618 _v8Isolate->Exit();636 _v8Isolate->Exit();
619 _v8Locker.reset(nullptr);637 _v8Locker.reset(nullptr);
620 }638 }*/
621}639}
622 640
623void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::FunctionSignature getter,641void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::FunctionSignature getter,
@@ -638,14 +656,16 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun · 14 unmodified lines
638 qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent;656 qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent;
639#endif657#endif
640 658
641 bool is_isolate_exit_needed = false;659 /*bool is_isolate_exit_needed = false;
642 if(!_v8Isolate->IsCurrent() && !_v8Locker) {660 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
643 // V8TODO: Theoretically only script thread should access this, so it should be safe661 // V8TODO: Theoretically only script thread should access this, so it should be safe
644 _v8Locker.reset(new v8::Locker(_v8Isolate));662 _v8Locker.reset(new v8::Locker(_v8Isolate));
645 _v8Isolate->Enter();663 _v8Isolate->Enter();
646 is_isolate_exit_needed = true;664 is_isolate_exit_needed = true;
647 }665 }
648 {666 {*/
667 v8::Locker locker(_v8Isolate);
668 v8::Isolate::Scope isolateScope(_v8Isolate);
649 v8::HandleScope handleScope(_v8Isolate);669 v8::HandleScope handleScope(_v8Isolate);
650 v8::Context::Scope contextScope(getContext());670 v8::Context::Scope contextScope(getContext());
651 671
@@ -717,11 +737,11 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun · 65 unmodified lines
717 //globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);737 //globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);
718 //globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);738 //globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
719 }739 }
720 }740 /*}
721 if (is_isolate_exit_needed) {741 if (is_isolate_exit_needed) {
722 _v8Isolate->Exit();742 _v8Isolate->Exit();
723 _v8Locker.reset(nullptr);743 _v8Locker.reset(nullptr);
724 }744 }*/
725}745}
726 746
727ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,747ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
@@ -730,42 +750,59 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 2 unmodified lines
730 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {750 if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
731 return nullValue();751 return nullValue();
732 }752 }
733 Q_ASSERT(!isEvaluating());753 _evaluatingCounter++;
734 _isEvaluating = true;754 v8::Locker locker(_v8Isolate);
755 v8::Isolate::Scope isolateScope(_v8Isolate);
735 v8::HandleScope handleScope(_v8Isolate);756 v8::HandleScope handleScope(_v8Isolate);
736 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
737 ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
738 if (unwrappedProgram == nullptr) {
739 _isEvaluating = false;
740 return nullValue();
741 }
742 const V8ScriptProgram& program = unwrappedProgram->toV8Value();
743 757
744 const auto fileName = unwrappedProgram->fileName();758 v8::Local<v8::Object> closureObject;
745 const auto shortName = QUrl(fileName).fileName();759 //v8::Local<v8::Value> oldGlobal;
760 v8::Local<v8::Value> closureGlobal;
761 ScriptValueV8Wrapper* unwrappedClosure;
762 ScriptProgramV8Wrapper* unwrappedProgram;
746 763
747 ScriptValueV8Wrapper* unwrappedClosure = ScriptValueV8Wrapper::unwrap(_closure);764 {
748 if (unwrappedClosure == nullptr) {765 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
749 _isEvaluating = false;766 unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
750 return nullValue();767 if (unwrappedProgram == nullptr) {
751 }768 _evaluatingCounter--;
752 const V8ScriptValue& closure = unwrappedClosure->toV8Value();769 qDebug(scriptengine) << "Cannot unwrap program for closure";
753 if (!closure.constGet()->IsObject()) {770 Q_ASSERT(false);
754 _isEvaluating = false;771 return nullValue();
755 return nullValue();772 }
756 }773 // V8TODO: is another context switch necessary after unwrapping closure?
757 const v8::Local<v8::Object> closureObject = v8::Local<v8::Object>::Cast(closure.constGet());
758 774
759 v8::Local<v8::Value> oldGlobal;775 const auto fileName = unwrappedProgram->fileName();
760 v8::Local<v8::Value> closureGlobal;776 const auto shortName = QUrl(fileName).fileName();
761 if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked()).ToLocal(&closureGlobal)) {
762 _isEvaluating = false;
763 return nullValue();
764 }
765 777
766 _v8Context.Get(_v8Isolate)->Exit();778 unwrappedClosure = ScriptValueV8Wrapper::unwrap(_closure);
767 _v8Context.Get(_v8Isolate)->DetachGlobal();779 if (unwrappedClosure == nullptr) {
768 oldGlobal = _v8Context.Get(_v8Isolate)->Global();780 _evaluatingCounter--;
781 qDebug(scriptengine) << "Cannot unwrap closure";
782 Q_ASSERT(false);
783 return nullValue();
784 }
785
786 const V8ScriptValue& closure = unwrappedClosure->toV8Value();
787 const V8ScriptProgram& program = unwrappedProgram->toV8Value();
788 if (!closure.constGet()->IsObject()) {
789 _evaluatingCounter--;
790 qDebug(scriptengine) << "Unwrapped closure is not an object";
791 Q_ASSERT(false);
792 return nullValue();
793 }
794 closureObject = v8::Local<v8::Object>::Cast(closure.constGet());
795
796 if (!closureObject->Get(closure.constGetContext(), v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked())
797 .ToLocal(&closureGlobal)) {
798 _evaluatingCounter--;
799 qDebug(scriptengine) << "Cannot get global from unwrapped closure";
800 Q_ASSERT(false);
801 return nullValue();
802 }
803 }
804 //_v8Context.Get(_v8Isolate)->DetachGlobal();
805 //oldGlobal = _v8Context.Get(_v8Isolate)->Global();
769 v8::Local<v8::Context> closureContext;806 v8::Local<v8::Context> closureContext;
770 807
771 if (closureGlobal->IsObject()) {808 if (closureGlobal->IsObject()) {
@@ -775,61 +812,71 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 3 unmodified lines
775 closureContext = v8::Context::New(_v8Isolate, nullptr, v8::Local<v8::ObjectTemplate>(), closureGlobal);812 closureContext = v8::Context::New(_v8Isolate, nullptr, v8::Local<v8::ObjectTemplate>(), closureGlobal);
776 //setGlobalObject(global);813 //setGlobalObject(global);
777 } else {814 } else {
778 closureContext = v8::Context::New(_v8Isolate, nullptr, v8::Local<v8::ObjectTemplate>(), oldGlobal);815 closureContext = v8::Context::New(_v8Isolate);
779 }816 }
780 817
818 ScriptValue result;
781 //auto context = pushContext();819 //auto context = pushContext();
782 820 {
783 v8::Local<v8::Value> thiz;821 v8::Context::Scope contextScope(closureContext);
784 // V8TODO: not sure if "this" doesn't exist or is empty in some cases822 const V8ScriptValue& closure = unwrappedClosure->toV8Value();
785 if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked()).ToLocal(&thiz)) {823 if (!unwrappedProgram->compile()) {
786 _isEvaluating = false;824 qDebug(scriptengine) << "Can't compile script for evaluating in closure";
787 return nullValue();825 Q_ASSERT(false);
788 }826 return nullValue();
789 //thiz = closure.property("this");827 }
790 if (thiz->IsObject()) {828 const V8ScriptProgram& program = unwrappedProgram->toV8Value();
829
830 v8::Local<v8::Value> thiz;
831 // V8TODO: not sure if "this" doesn't exist or is empty in some cases
832 if (!closureObject->Get(closure.constGetContext(), v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked())
833 .ToLocal(&thiz)) {
834 _evaluatingCounter--;
835 qDebug(scriptengine) << "Empty this object in closure";
836 Q_ASSERT(false);
837 return nullValue();
838 }
839 //thiz = closure.property("this");
840 if (thiz->IsObject()) {
791#ifdef DEBUG_JS841#ifdef DEBUG_JS
792 qCDebug(shared) << " setting this = closure.this" << shortName;842 qCDebug(shared) << " setting this = closure.this" << shortName;
793#endif843#endif
794 //V8TODO I don't know how to do this in V8, will adding "this" to global object work?844 //V8TODO I don't know how to do this in V8, will adding "this" to global object work?
795 closureContext->Global()->Set(closureContext, v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked(), thiz);845 closureContext->Global()->Set(closureContext, v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked(), thiz);
796 //context->setThisObject(thiz);846 //context->setThisObject(thiz);
797 }847 }
798 848
799 //context->pushScope(closure);849 //context->pushScope(closure);
800#ifdef DEBUG_JS850#ifdef DEBUG_JS
801 qCDebug(shared) << QString("[%1] evaluateInClosure %2").arg(isEvaluating()).arg(shortName);851 qCDebug(shared) << QString("[%1] evaluateInClosure %2").arg(isEvaluating()).arg(shortName);
802#endif852#endif
803 ScriptValue result;853 {
804 {854 v8::TryCatch tryCatch(getIsolate());
805 v8::TryCatch tryCatch(getIsolate());855 auto maybeResult = program.constGet()->Run(closureContext);
806 auto maybeResult = program.constGet()->Run(closureContext);856 v8::Local<v8::Value> v8Result;
807 v8::Local<v8::Value> v8Result;857 if (!maybeResult.ToLocal(&v8Result)) {
808 if (!maybeResult.ToLocal(&v8Result)) {858 v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception());
809 v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception());859 QString errorMessage = QString(*utf8Value);
810 QString errorMessage = QString(*utf8Value);860 qWarning(scriptengine) << __FUNCTION__ << "---------- hasCaught:" << errorMessage;
811 qWarning() << __FUNCTION__ << "---------- hasCaught:" << errorMessage;861 //V8TODO: better error reporting
812 //V8TODO: better error reporting862 }
813 }
814 863
815 if (hasUncaughtException()) {864 if (hasUncaughtException()) {
816 auto err = cloneUncaughtException(__FUNCTION__);865 auto err = cloneUncaughtException(__FUNCTION__);
817#ifdef DEBUG_JS_EXCEPTIONS866#ifdef DEBUG_JS_EXCEPTIONS
818 qCWarning(shared) << __FUNCTION__ << "---------- hasCaught:" << err.toString() << result.toString();867 qCWarning(shared) << __FUNCTION__ << "---------- hasCaught:" << err.toString() << result.toString();
819 err.setProperty("_result", result);868 err.setProperty("_result", result);
820#endif869#endif
821 result = err;870 result = err;
822 } else {871 } else {
823 result = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, v8Result)));872 result = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, v8Result)));
873 }
824 }874 }
825 }
826#ifdef DEBUG_JS875#ifdef DEBUG_JS
827 qCDebug(shared) << QString("[%1] //evaluateInClosure %2").arg(isEvaluating()).arg(shortName);876 qCDebug(shared) << QString("[%1] //evaluateInClosure %2").arg(isEvaluating()).arg(shortName);
828#endif877#endif
829 //popContext();878 //popContext();
830 closureContext->Exit();879 }
831 _v8Context.Get(_v8Isolate)->Enter();
832
833 //This is probably unnecessary in V8880 //This is probably unnecessary in V8
834 /*if (oldGlobal.isValid()) {881 /*if (oldGlobal.isValid()) {
835#ifdef DEBUG_JS882#ifdef DEBUG_JS
@@ -838,8 +885,8 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 2 unmodified lines
838 setGlobalObject(oldGlobal);885 setGlobalObject(oldGlobal);
839 }*/886 }*/
840 887
841 //_v8Context.Get(_v8Isolate)->Enter();888 closureContext->DetachGlobal();
842 _isEvaluating = false;889 _evaluatingCounter--;
843 return result;890 return result;
844}891}
845 892
@@ -865,8 +912,9 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 19 unmodified lines
865 // Compile and check syntax912 // Compile and check syntax
866 // V8TODO: Could these all be replaced with checkSyntax function from wrapper?913 // V8TODO: Could these all be replaced with checkSyntax function from wrapper?
867 Q_ASSERT(!_v8Isolate->IsDead());914 Q_ASSERT(!_v8Isolate->IsDead());
868 Q_ASSERT(!isEvaluating());915 _evaluatingCounter++;
869 _isEvaluating = true;916 v8::Locker locker(_v8Isolate);
917 v8::Isolate::Scope isolateScope(_v8Isolate);
870 v8::HandleScope handleScope(_v8Isolate);918 v8::HandleScope handleScope(_v8Isolate);
871 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));919 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
872 v8::TryCatch tryCatch(getIsolate());920 v8::TryCatch tryCatch(getIsolate());
@@ -896,7 +944,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 23 unmodified lines
896 auto err = makeError(newValue(errorMessage));944 auto err = makeError(newValue(errorMessage));
897 raiseException(err);945 raiseException(err);
898 maybeEmitUncaughtException("compile");946 maybeEmitUncaughtException("compile");
899 _isEvaluating = false;947 _evaluatingCounter--;
900 return err;948 return err;
901 }949 }
902 qCDebug(scriptengine) << "Script compilation succesful: " << fileName;950 qCDebug(scriptengine) << "Script compilation succesful: " << fileName;
@@ -930,11 +978,11 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 27 unmodified lines
930 //V8TODO978 //V8TODO
931 //raiseException(errorValue);979 //raiseException(errorValue);
932 //maybeEmitUncaughtException("evaluate");980 //maybeEmitUncaughtException("evaluate");
933 _isEvaluating = false;981 _evaluatingCounter--;
934 return errorValue;982 return errorValue;
935 }983 }
936 V8ScriptValue resultValue(_v8Isolate, result);984 V8ScriptValue resultValue(_v8Isolate, result);
937 _isEvaluating = false;985 _evaluatingCounter--;
938 return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));986 return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
939}987}
940 988
@@ -979,19 +1027,20 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 38 unmodified lines
979 Q_ARG(const ScriptProgramPointer&, program));1027 Q_ARG(const ScriptProgramPointer&, program));
980 return result;1028 return result;
981 }1029 }
982 Q_ASSERT(!isEvaluating());1030 _evaluatingCounter++;
983 _isEvaluating = true;1031 /*bool is_isolate_exit_needed = false;
984 bool is_isolate_exit_needed = false;
985 if(!_v8Isolate->IsCurrent() && !_v8Locker) {1032 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
986 // V8TODO: Theoretically only script thread should access this, so it should be safe1033 // V8TODO: Theoretically only script thread should access this, so it should be safe
987 _v8Locker.reset(new v8::Locker(_v8Isolate));1034 _v8Locker.reset(new v8::Locker(_v8Isolate));
988 _v8Isolate->Enter();1035 _v8Isolate->Enter();
989 is_isolate_exit_needed = true;1036 is_isolate_exit_needed = true;
990 }1037 }*/
991 ScriptValue errorValue;1038 ScriptValue errorValue;
992 ScriptValue resultValue;1039 ScriptValue resultValue;
993 bool hasFailed = false;1040 bool hasFailed = false;
994 {1041 {
1042 v8::Locker locker(_v8Isolate);
1043 v8::Isolate::Scope isolateScope(_v8Isolate);
995 v8::HandleScope handleScope(_v8Isolate);1044 v8::HandleScope handleScope(_v8Isolate);
996 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1045 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
997 ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);1046 ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
@@ -1039,11 +1088,11 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 41 unmodified lines
1039 resultValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValueV8)));1088 resultValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValueV8)));
1040 }1089 }
1041 }1090 }
1042 _isEvaluating = false;1091 _evaluatingCounter--;
1043 if (is_isolate_exit_needed) {1092 /*if (is_isolate_exit_needed) {
1044 _v8Isolate->Exit();1093 _v8Isolate->Exit();
1045 _v8Locker.reset(nullptr);1094 _v8Locker.reset(nullptr);
1046 }1095 }*/
1047 if (hasFailed) {1096 if (hasFailed) {
1048 return errorValue;1097 return errorValue;
1049 } else {1098 } else {
@@ -1066,6 +1115,8 @@ void ScriptEngineV8::updateMemoryCost(const qint64& deltaSize) { · 16 unmodified lines
1066// ScriptEngine implementation1115// ScriptEngine implementation
1067 1116
1068ScriptValue ScriptEngineV8::globalObject() const {1117ScriptValue ScriptEngineV8::globalObject() const {
1118 v8::Locker locker(_v8Isolate);
1119 v8::Isolate::Scope isolateScope(_v8Isolate);
1069 v8::HandleScope handleScope(_v8Isolate);1120 v8::HandleScope handleScope(_v8Isolate);
1070 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1121 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1071 V8ScriptValue global(_v8Isolate, getConstContext()->Global());// = QScriptEngine::globalObject(); // can't cache the value as it may change1122 V8ScriptValue global(_v8Isolate, getConstContext()->Global());// = QScriptEngine::globalObject(); // can't cache the value as it may change
@@ -1077,6 +1128,8 @@ ScriptManager* ScriptEngineV8::manager() const { · 5 unmodified lines
1077}1128}
1078 1129
1079ScriptValue ScriptEngineV8::newArray(uint length) {1130ScriptValue ScriptEngineV8::newArray(uint length) {
1131 v8::Locker locker(_v8Isolate);
1132 v8::Isolate::Scope isolateScope(_v8Isolate);
1080 v8::HandleScope handleScope(_v8Isolate);1133 v8::HandleScope handleScope(_v8Isolate);
1081 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1134 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1082 V8ScriptValue result(_v8Isolate, v8::Array::New(_v8Isolate, static_cast<int>(length)));1135 V8ScriptValue result(_v8Isolate, v8::Array::New(_v8Isolate, static_cast<int>(length)));
@@ -1084,6 +1137,8 @@ ScriptValue ScriptEngineV8::newArray(uint length) { · 1 unmodified line
1084}1137}
1085 1138
1086ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) {1139ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) {
1140 v8::Locker locker(_v8Isolate);
1141 v8::Isolate::Scope isolateScope(_v8Isolate);
1087 v8::HandleScope handleScope(_v8Isolate);1142 v8::HandleScope handleScope(_v8Isolate);
1088 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1143 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1089 //V8TODO: this will leak memory1144 //V8TODO: this will leak memory
@@ -1101,14 +1156,33 @@ ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) { · 11 unmodified lines
1101}1156}
1102 1157
1103ScriptValue ScriptEngineV8::newObject() {1158ScriptValue ScriptEngineV8::newObject() {
1104 v8::HandleScope handleScope(_v8Isolate);1159 /*bool is_isolate_exit_needed = false;
1105 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1160 if(!_v8Isolate->IsCurrent() && !_v8Locker) {
1106 V8ScriptValue result(_v8Isolate, v8::Object::New(_v8Isolate));1161 // V8TODO: Theoretically only script thread should access this, so it should be safe
1107 return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));1162 _v8Locker.reset(new v8::Locker(_v8Isolate));
1163 _v8Isolate->Enter();
1164 is_isolate_exit_needed = true;
1165 }*/
1166 ScriptValue result;
1167 {
1168 v8::Locker locker(_v8Isolate);
1169 v8::Isolate::Scope isolateScope(_v8Isolate);
1170 v8::HandleScope handleScope(_v8Isolate);
1171 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1172 V8ScriptValue resultV8 = V8ScriptValue(_v8Isolate, v8::Object::New(_v8Isolate));
1173 result = ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultV8)));
1174 }
1175 /*if (is_isolate_exit_needed) {
1176 _v8Isolate->Exit();
1177 _v8Locker.reset(nullptr);
1178 }*/
1179 return result;
1108}1180}
1109 1181
1110ScriptValue ScriptEngineV8::newMethod(QObject* object, V8ScriptValue lifetime,1182ScriptValue ScriptEngineV8::newMethod(QObject* object, V8ScriptValue lifetime,
1111 const QList<QMetaMethod>& metas, int numMaxParams) {1183 const QList<QMetaMethod>& metas, int numMaxParams) {
1184 v8::Locker locker(_v8Isolate);
1185 v8::Isolate::Scope isolateScope(_v8Isolate);
1112 v8::HandleScope handleScope(_v8Isolate);1186 v8::HandleScope handleScope(_v8Isolate);
1113 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1187 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1114 V8ScriptValue result(ScriptMethodV8Proxy::newMethod(this, object, lifetime, metas, numMaxParams));1188 V8ScriptValue result(ScriptMethodV8Proxy::newMethod(this, object, lifetime, metas, numMaxParams));
@@ -1120,6 +1194,8 @@ ScriptProgramPointer ScriptEngineV8::newProgram(const QString& sourceCode, const · 5 unmodified lines
1120 //V8TODO: should it be compiled on creation?1194 //V8TODO: should it be compiled on creation?
1121 //V8ScriptProgram result(sourceCode, fileName);1195 //V8ScriptProgram result(sourceCode, fileName);
1122 1196
1197 v8::Locker locker(_v8Isolate);
1198 v8::Isolate::Scope isolateScope(_v8Isolate);
1123 v8::HandleScope handleScope(_v8Isolate);1199 v8::HandleScope handleScope(_v8Isolate);
1124 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1200 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1125 return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);1201 return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
@@ -1128,6 +1204,8 @@ ScriptProgramPointer ScriptEngineV8::newProgram(const QString& sourceCode, const · 2 unmodified lines
1128ScriptValue ScriptEngineV8::newQObject(QObject* object,1204ScriptValue ScriptEngineV8::newQObject(QObject* object,
1129 ScriptEngine::ValueOwnership ownership,1205 ScriptEngine::ValueOwnership ownership,
1130 const ScriptEngine::QObjectWrapOptions& options) {1206 const ScriptEngine::QObjectWrapOptions& options) {
1207 v8::Locker locker(_v8Isolate);
1208 v8::Isolate::Scope isolateScope(_v8Isolate);
1131 v8::HandleScope handleScope(_v8Isolate);1209 v8::HandleScope handleScope(_v8Isolate);
1132 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1210 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1133 V8ScriptValue result = ScriptObjectV8Proxy::newQObject(this, object, ownership, options);1211 V8ScriptValue result = ScriptObjectV8Proxy::newQObject(this, object, ownership, options);
@@ -1135,6 +1213,8 @@ ScriptValue ScriptEngineV8::newQObject(QObject* object, · 1 unmodified line
1135}1213}
1136 1214
1137ScriptValue ScriptEngineV8::newValue(bool value) {1215ScriptValue ScriptEngineV8::newValue(bool value) {
1216 v8::Locker locker(_v8Isolate);
1217 v8::Isolate::Scope isolateScope(_v8Isolate);
1138 v8::HandleScope handleScope(_v8Isolate);1218 v8::HandleScope handleScope(_v8Isolate);
1139 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1219 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1140 V8ScriptValue result(_v8Isolate, v8::Boolean::New(_v8Isolate, value));1220 V8ScriptValue result(_v8Isolate, v8::Boolean::New(_v8Isolate, value));
@@ -1142,6 +1222,8 @@ ScriptValue ScriptEngineV8::newValue(bool value) { · 1 unmodified line
1142}1222}
1143 1223
1144ScriptValue ScriptEngineV8::newValue(int value) {1224ScriptValue ScriptEngineV8::newValue(int value) {
1225 v8::Locker locker(_v8Isolate);
1226 v8::Isolate::Scope isolateScope(_v8Isolate);
1145 v8::HandleScope handleScope(_v8Isolate);1227 v8::HandleScope handleScope(_v8Isolate);
1146 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1228 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1147 V8ScriptValue result(_v8Isolate, v8::Integer::New(_v8Isolate, value));1229 V8ScriptValue result(_v8Isolate, v8::Integer::New(_v8Isolate, value));
@@ -1149,6 +1231,8 @@ ScriptValue ScriptEngineV8::newValue(int value) { · 1 unmodified line
1149}1231}
1150 1232
1151ScriptValue ScriptEngineV8::newValue(uint value) {1233ScriptValue ScriptEngineV8::newValue(uint value) {
1234 v8::Locker locker(_v8Isolate);
1235 v8::Isolate::Scope isolateScope(_v8Isolate);
1152 v8::HandleScope handleScope(_v8Isolate);1236 v8::HandleScope handleScope(_v8Isolate);
1153 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1237 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1154 V8ScriptValue result(_v8Isolate, v8::Uint32::New(_v8Isolate, value));1238 V8ScriptValue result(_v8Isolate, v8::Uint32::New(_v8Isolate, value));
@@ -1156,6 +1240,8 @@ ScriptValue ScriptEngineV8::newValue(uint value) { · 1 unmodified line
1156}1240}
1157 1241
1158ScriptValue ScriptEngineV8::newValue(double value) {1242ScriptValue ScriptEngineV8::newValue(double value) {
1243 v8::Locker locker(_v8Isolate);
1244 v8::Isolate::Scope isolateScope(_v8Isolate);
1159 v8::HandleScope handleScope(_v8Isolate);1245 v8::HandleScope handleScope(_v8Isolate);
1160 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1246 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1161 V8ScriptValue result(_v8Isolate, v8::Number::New(_v8Isolate, value));1247 V8ScriptValue result(_v8Isolate, v8::Number::New(_v8Isolate, value));
@@ -1163,6 +1249,8 @@ ScriptValue ScriptEngineV8::newValue(double value) { · 1 unmodified line
1163}1249}
1164 1250
1165ScriptValue ScriptEngineV8::newValue(const QString& value) {1251ScriptValue ScriptEngineV8::newValue(const QString& value) {
1252 v8::Locker locker(_v8Isolate);
1253 v8::Isolate::Scope isolateScope(_v8Isolate);
1166 v8::HandleScope handleScope(_v8Isolate);1254 v8::HandleScope handleScope(_v8Isolate);
1167 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1255 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1168 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.toStdString().c_str(), v8::NewStringType::kNormal).ToLocalChecked();1256 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.toStdString().c_str(), v8::NewStringType::kNormal).ToLocalChecked();
@@ -1171,6 +1259,8 @@ ScriptValue ScriptEngineV8::newValue(const QString& value) { · 2 unmodified lines
1171}1259}
1172 1260
1173ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) {1261ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) {
1262 v8::Locker locker(_v8Isolate);
1263 v8::Isolate::Scope isolateScope(_v8Isolate);
1174 v8::HandleScope handleScope(_v8Isolate);1264 v8::HandleScope handleScope(_v8Isolate);
1175 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1265 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1176 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.latin1(), v8::NewStringType::kNormal).ToLocalChecked();1266 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.latin1(), v8::NewStringType::kNormal).ToLocalChecked();
@@ -1179,6 +1269,8 @@ ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) { · 2 unmodified lines
1179}1269}
1180 1270
1181ScriptValue ScriptEngineV8::newValue(const char* value) {1271ScriptValue ScriptEngineV8::newValue(const char* value) {
1272 v8::Locker locker(_v8Isolate);
1273 v8::Isolate::Scope isolateScope(_v8Isolate);
1182 v8::HandleScope handleScope(_v8Isolate);1274 v8::HandleScope handleScope(_v8Isolate);
1183 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1275 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1184 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value, v8::NewStringType::kNormal).ToLocalChecked();1276 v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value, v8::NewStringType::kNormal).ToLocalChecked();
@@ -1187,6 +1279,8 @@ ScriptValue ScriptEngineV8::newValue(const char* value) { · 2 unmodified lines
1187}1279}
1188 1280
1189ScriptValue ScriptEngineV8::newVariant(const QVariant& value) {1281ScriptValue ScriptEngineV8::newVariant(const QVariant& value) {
1282 v8::Locker locker(_v8Isolate);
1283 v8::Isolate::Scope isolateScope(_v8Isolate);
1190 v8::HandleScope handleScope(_v8Isolate);1284 v8::HandleScope handleScope(_v8Isolate);
1191 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1285 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1192 V8ScriptValue result = castVariantToValue(value);1286 V8ScriptValue result = castVariantToValue(value);
@@ -1236,7 +1330,7 @@ bool ScriptEngineV8::hasUncaughtException() const { · 43 unmodified lines
1236 1330
1237bool ScriptEngineV8::isEvaluating() const {1331bool ScriptEngineV8::isEvaluating() const {
1238 //return QScriptEngine::isEvaluating();1332 //return QScriptEngine::isEvaluating();
1239 return _isEvaluating;1333 return _evaluatingCounter > 0;
1240 return false;1334 return false;
1241}1335}
1242 1336
@@ -1274,6 +1368,8 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 31 unmodified lines
1274 //auto functionTemplate = v8::FunctionTemplate::New(_v8Isolate, v8FunctionCallback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), length);1368 //auto functionTemplate = v8::FunctionTemplate::New(_v8Isolate, v8FunctionCallback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), length);
1275 //auto functionData = v8::Object::New(_v8Isolate);1369 //auto functionData = v8::Object::New(_v8Isolate);
1276 //functionData->setIn1370 //functionData->setIn
1371 v8::Locker locker(_v8Isolate);
1372 v8::Isolate::Scope isolateScope(_v8Isolate);
1277 v8::HandleScope handleScope(_v8Isolate);1373 v8::HandleScope handleScope(_v8Isolate);
1278 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1374 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1279 auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);1375 auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);
@@ -1299,6 +1395,8 @@ void ScriptEngineV8::setObjectName(const QString& name) { · 19 unmodified lines
1299 1395
1300//V8TODO1396//V8TODO
1301bool ScriptEngineV8::setProperty(const char* name, const QVariant& value) {1397bool ScriptEngineV8::setProperty(const char* name, const QVariant& value) {
1398 v8::Locker locker(_v8Isolate);
1399 v8::Isolate::Scope isolateScope(_v8Isolate);
1302 v8::HandleScope handleScope(_v8Isolate);1400 v8::HandleScope handleScope(_v8Isolate);
1303 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1401 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1304 v8::Local<v8::Object> global = getContext()->Global();1402 v8::Local<v8::Object> global = getContext()->Global();
@@ -1322,14 +1420,14 @@ void ScriptEngineV8::setThread(QThread* thread) { · 17 unmodified lines
1322 qDebug() << "Script engine " << objectName() << " exited isolate";1420 qDebug() << "Script engine " << objectName() << " exited isolate";
1323 }1421 }
1324 Q_ASSERT(QObject::thread() == QThread::currentThread());1422 Q_ASSERT(QObject::thread() == QThread::currentThread());
1325 if (_v8Locker) {1423 /*if (_v8Locker) {
1326 _v8Locker.reset();1424 _v8Locker.reset();
1327 }1425 }*/
1328 moveToThread(thread);1426 moveToThread(thread);
1329 qDebug() << "Moved script engine " << objectName() << " to different thread";1427 qDebug() << "Moved script engine " << objectName() << " to different thread";
1330}1428}
1331 1429
1332void ScriptEngineV8::enterIsolateOnThisThread() {1430/*void ScriptEngineV8::enterIsolateOnThisThread() {
1333 Q_ASSERT(thread() == QThread::currentThread());1431 Q_ASSERT(thread() == QThread::currentThread());
1334 Q_ASSERT(!_v8Locker);1432 Q_ASSERT(!_v8Locker);
1335 _v8Locker.reset(new v8::Locker(_v8Isolate));1433 _v8Locker.reset(new v8::Locker(_v8Isolate));
@@ -1337,7 +1435,7 @@ void ScriptEngineV8::enterIsolateOnThisThread() { · 1 unmodified line
1337 _v8Isolate->Enter();1435 _v8Isolate->Enter();
1338 qDebug() << "Script engine " << objectName() << " entered isolate on a new thread";1436 qDebug() << "Script engine " << objectName() << " entered isolate on a new thread";
1339 }1437 }
1340}1438}*/
1341 1439
1342 1440
1343ScriptValue ScriptEngineV8::uncaughtException() const {1441ScriptValue ScriptEngineV8::uncaughtException() const {
@@ -1367,6 +1465,8 @@ bool ScriptEngineV8::raiseException(const ScriptValue& exception) { · 23 unmodified lines
1367}1465}
1368 1466
1369ScriptValue ScriptEngineV8::create(int type, const void* ptr) {1467ScriptValue ScriptEngineV8::create(int type, const void* ptr) {
1468 v8::Locker locker(_v8Isolate);
1469 v8::Isolate::Scope isolateScope(_v8Isolate);
1370 v8::HandleScope handleScope(_v8Isolate);1470 v8::HandleScope handleScope(_v8Isolate);
1371 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1471 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1372 QVariant variant(type, ptr);1472 QVariant variant(type, ptr);
@@ -1375,6 +1475,8 @@ ScriptValue ScriptEngineV8::create(int type, const void* ptr) { · 2 unmodified lines
1375}1475}
1376 1476
1377QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) {1477QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) {
1478 v8::Locker locker(_v8Isolate);
1479 v8::Isolate::Scope isolateScope(_v8Isolate);
1378 v8::HandleScope handleScope(_v8Isolate);1480 v8::HandleScope handleScope(_v8Isolate);
1379 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1481 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1380 ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(value);1482 ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(value);
@@ -1397,20 +1499,44 @@ QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) { · 16 unmodified lines
1397}1499}
1398 1500
1399void ScriptEngineV8::compileTest() {1501void ScriptEngineV8::compileTest() {
1400 //v8::Locker locker(_v8Isolate);1502 v8::Locker locker(_v8Isolate);
1401 //v8::Isolate::Scope isolateScope(_v8Isolate);1503 v8::Isolate::Scope isolateScope(_v8Isolate);
1402 v8::HandleScope handleScope(_v8Isolate);1504 v8::HandleScope handleScope(_v8Isolate);
1403 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1505 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1404 v8::Local<v8::Script> script;1506 v8::Local<v8::Script> script;
1405 v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(),"test").ToLocalChecked());1507 v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(),"test").ToLocalChecked());
1406 if (v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), "print(\"hello world\");").ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {1508 if (v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), "print(\"hello world\");").ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
1407 qCDebug(scriptengine) << "Compile test succesful";1509 qCDebug(scriptengine) << "Compile test successful";
1408 } else {1510 } else {
1409 qCDebug(scriptengine) << "Compile test failed";1511 qCDebug(scriptengine) << "Compile test failed";
1410 Q_ASSERT(false);1512 Q_ASSERT(false);
1411 }1513 }
1412}1514}
1413 1515
1516QString ScriptEngineV8::scriptValueDebugDetails(ScriptValue &value) {
1517 V8ScriptValue v8Value = ScriptValueV8Wrapper::fullUnwrap(this, value);
1518 return scriptValueDebugDetailsV8(v8Value);
1519}
1520
1521QString ScriptEngineV8::scriptValueDebugDetailsV8(const V8ScriptValue &v8Value) {
1522 v8::Locker locker(_v8Isolate);
1523 v8::Isolate::Scope isolateScope(_v8Isolate);
1524 v8::HandleScope handleScope(_v8Isolate);
1525 v8::Context::Scope contextScope(getContext());
1526
1527 QString parentValueQString("");
1528 v8::Local<v8::String> parentValueString;
1529 if (v8Value.constGet()->ToDetailString(getContext()).ToLocal(&parentValueString)) {
1530 parentValueQString = QString(*v8::String::Utf8Value(_v8Isolate, parentValueString));
1531 }
1532 QString JSONQString;
1533 v8::Local<v8::String> JSONString;
1534 if (v8::JSON::Stringify(getContext(), v8Value.constGet()).ToLocal(&JSONString)) {
1535 JSONQString = QString(*v8::String::Utf8Value(_v8Isolate, JSONString));
1536 }
1537 return parentValueQString + QString(" JSON: ") + JSONQString;
1538}
1539
1414/*QStringList ScriptEngineV8::getCurrentStackTrace() {1540/*QStringList ScriptEngineV8::getCurrentStackTrace() {
1415 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(_v8Isolate, 100);1541 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(_v8Isolate, 100);
1416 QStringList backtrace;1542 QStringList backtrace;