Showing the changes to libraries/script-engine/src/v8/ScriptEngineV8.cpp (1 of 4 files). Show all
Unified · Split
| @@ -760,6 +760,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 759 unmodified lines | ||
| 760 | 760 | v8::Local<v8::Value> closureGlobal; |
| 761 | 761 | ScriptValueV8Wrapper* unwrappedClosure; |
| 762 | 762 | ScriptProgramV8Wrapper* unwrappedProgram; |
| 763 | + v8::Local<v8::Context> oldContext = getContext(); | |
| 763 | 764 | |
| 764 | 765 | { |
| 765 | 766 | v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); |
| @@ -792,6 +793,10 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 26 unmodified lines | ||
| 792 | 793 | return nullValue(); |
| 793 | 794 | } |
| 794 | 795 | closureObject = v8::Local<v8::Object>::Cast(closure.constGet()); |
| 796 | + qDebug() << "Closure object members:" << scriptValueDebugListMembersV8(closure); | |
| 797 | + v8::Local<v8::Object> testObject = v8::Object::New(_v8Isolate); | |
| 798 | + testObject->Set(getContext(), v8::String::NewFromUtf8(_v8Isolate, "test_value").ToLocalChecked(), closureObject); | |
| 799 | + qDebug() << "Test object members:" << scriptValueDebugListMembersV8(V8ScriptValue(_v8Isolate, testObject)); | |
| 795 | 800 | |
| 796 | 801 | if (!closureObject->Get(closure.constGetContext(), v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked()) |
| 797 | 802 | .ToLocal(&closureGlobal)) { |
| @@ -806,7 +811,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 8 unmodified lines | ||
| 806 | 811 | //oldGlobal = _v8Context.Get(_v8Isolate)->Global(); |
| 807 | 812 | v8::Local<v8::Context> closureContext; |
| 808 | 813 | |
| 809 | − // V8TODO | |
| 814 | + // V8TODO V8 cannot use arbitrary objects as global objects | |
| 810 | 815 | /*if (closureGlobal->IsObject()) { |
| 811 | 816 | #ifdef DEBUG_JS |
| 812 | 817 | qCDebug(shared) << " setting global = closure.global" << shortName; |
| @@ -817,7 +822,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 4 unmodified lines | ||
| 817 | 822 | } else { |
| 818 | 823 | closureContext = v8::Context::New(_v8Isolate); |
| 819 | 824 | }*/ |
| 820 | − closureContext = v8::Context::New(_v8Isolate, nullptr, v8::Local<v8::ObjectTemplate>(), closureObject); | |
| 825 | + closureContext = v8::Context::New(_v8Isolate); | |
| 821 | 826 | |
| 822 | 827 | ScriptValue result; |
| 823 | 828 | //auto context = pushContext(); |
| @@ -861,8 +866,33 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 37 unmodified lines | ||
| 861 | 866 | #endif |
| 862 | 867 | { |
| 863 | 868 | v8::TryCatch tryCatch(getIsolate()); |
| 864 | − //qDebug(scriptengine) << "Closure before run:" << scriptValueDebugDetailsV8(closure); | |
| 865 | − auto maybeResult = program.constGet()->Run(closureContext); | |
| 869 | + // Since V8 cannot use arbitrary object as global object, objects from main global need to be copied to closure's global object | |
| 870 | + auto oldGlobalMemberNames = oldContext->Global()->GetPropertyNames(oldContext).ToLocalChecked(); | |
| 871 | + for (int i = 0; i < oldGlobalMemberNames->Length(); i++) { | |
| 872 | + auto name = oldGlobalMemberNames->Get(closureContext, i).ToLocalChecked(); | |
| 873 | + closureContext->Global()->Set(closureContext, name, oldContext->Global()->Get(oldContext, name).ToLocalChecked()); | |
| 874 | + } | |
| 875 | + // Objects from closure need to be copied to global object too | |
| 876 | + auto closureMemberNames = closureObject->GetPropertyNames(closureContext).ToLocalChecked(); | |
| 877 | + for (int i = 0; i < closureMemberNames->Length(); i++) { | |
| 878 | + auto name = closureMemberNames->Get(closureContext, i).ToLocalChecked(); | |
| 879 | + closureContext->Global()->Set(closureContext, name, closureObject->Get(closureContext, name).ToLocalChecked()); | |
| 880 | + } | |
| 881 | + // List members of closure global object | |
| 882 | + QString membersString(""); | |
| 883 | + if (closureContext->Global()->IsObject()) { | |
| 884 | + v8::Local<v8::String> membersStringV8; | |
| 885 | + v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(closureContext->Global()); | |
| 886 | + auto names = object->GetPropertyNames(closureContext).ToLocalChecked(); | |
| 887 | + if (v8::JSON::Stringify(closureContext, names).ToLocal(&membersStringV8)) { | |
| 888 | + membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8)); | |
| 889 | + } | |
| 890 | + membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8)); | |
| 891 | + } else { | |
| 892 | + membersString = QString(" Is not an object"); | |
| 893 | + } | |
| 894 | + qDebug(scriptengine) << "Closure global before run:" << membersString; | |
| 895 | + auto maybeResult = program.constGet()->GetUnboundScript()->BindToCurrentContext()->Run(closureContext); | |
| 866 | 896 | //qDebug(scriptengine) << "Closure after run:" << scriptValueDebugDetailsV8(closure); |
| 867 | 897 | v8::Local<v8::Value> v8Result; |
| 868 | 898 | if (!maybeResult.ToLocal(&v8Result)) { |
| @@ -897,7 +927,6 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 28 unmodified lines | ||
| 897 | 927 | setGlobalObject(oldGlobal); |
| 898 | 928 | }*/ |
| 899 | 929 | |
| 900 | − closureContext->DetachGlobal(); | |
| 901 | 930 | _evaluatingCounter--; |
| 902 | 931 | return result; |
| 903 | 932 | } |
| @@ -1546,7 +1575,7 @@ QString ScriptEngineV8::scriptValueDebugListMembersV8(const V8ScriptValue &v8Val · 642 unmodified lines | ||
| 1546 | 1575 | v8::Local<v8::String> membersStringV8; |
| 1547 | 1576 | v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value.constGet()); |
| 1548 | 1577 | auto names = object->GetPropertyNames(getContext()).ToLocalChecked(); |
| 1549 | − if (v8::JSON::Stringify(getContext(), object).ToLocal(&membersStringV8)) { | |
| 1578 | + if (v8::JSON::Stringify(getContext(), names).ToLocal(&membersStringV8)) { | |
| 1550 | 1579 | membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8)); |
| 1551 | 1580 | } |
| 1552 | 1581 | membersString = QString(*v8::String::Utf8Value(_v8Isolate, membersStringV8)); |