Showing the changes to libraries/script-engine/src/v8/ScriptEngineV8.cpp (1 of 6 files). Show all
Unified · Split
| @@ -294,7 +294,7 @@ ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8Scri · 293 unmodified lines | ||
| 294 | 294 | v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); |
| 295 | 295 | auto lambda = new Lambda(this, operation, data); |
| 296 | 296 | auto object = newQObject(lambda, ownership); |
| 297 | − //V8TODO? | |
| 297 | + //V8TODO - I'm not sure if this works | |
| 298 | 298 | auto call = object.property("call"); |
| 299 | 299 | call.setPrototype(object); // context->callee().prototype() === Lambda QObject |
| 300 | 300 | call.setData(ScriptValue(new ScriptValueV8Wrapper(this, data))); // context->callee().data() will === data param |
| @@ -334,8 +334,10 @@ V8ScriptValue Lambda::call() { · 33 unmodified lines | ||
| 334 | 334 | if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) { |
| 335 | 335 | return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); |
| 336 | 336 | } |
| 337 | − return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 338 | − // V8TODO: something is obviously wrong here, there's no call at all? | |
| 337 | + // V8TODO: it needs to be done in entirely different way for V8 | |
| 338 | + Q_ASSERT(false); | |
| 339 | + //return _operation(_engine->getContext(), _engine); | |
| 340 | + //return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate())); | |
| 339 | 341 | //return operation(static_cast<QScriptEngine*>(engine)->currentContext(), engine); |
| 340 | 342 | } |
| 341 | 343 | |
| @@ -379,30 +381,35 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) : · 37 unmodified lines | ||
| 379 | 381 | v8::V8::Initialize(); |
| 380 | 382 | } ); |
| 381 | 383 | _v8InitMutex.unlock(); |
| 382 | − v8::Isolate::CreateParams isolateParams; | |
| 383 | − isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); | |
| 384 | − _v8Isolate = v8::Isolate::New(isolateParams); | |
| 385 | − _v8Isolate->Enter(); | |
| 386 | − v8::HandleScope handleScope(_v8Isolate); | |
| 387 | − v8::Local<v8::Context> context = v8::Context::New(_v8Isolate); | |
| 388 | − Q_ASSERT(!context.IsEmpty()); | |
| 389 | − _v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context); | |
| 384 | + { | |
| 385 | + v8::Isolate::CreateParams isolateParams; | |
| 386 | + isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); | |
| 387 | + _v8Isolate = v8::Isolate::New(isolateParams); | |
| 388 | + _v8Isolate->Enter(); | |
| 389 | + v8::HandleScope handleScope(_v8Isolate); | |
| 390 | + v8::Local<v8::Context> context = v8::Context::New(_v8Isolate); | |
| 391 | + Q_ASSERT(!context.IsEmpty()); | |
| 392 | + v8::Context::Scope contextScope(context); | |
| 393 | + _v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context); | |
| 390 | 394 | |
| 391 | − registerSystemTypes(); | |
| 395 | + V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate)); | |
| 396 | + _nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue)); | |
| 392 | 397 | |
| 393 | − // V8TODO: dispose of isolate on ScriptEngineV8 destruction | |
| 394 | − //v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate)); | |
| 395 | − //_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null))); | |
| 396 | − V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate)); | |
| 397 | − _nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue)); | |
| 398 | + V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate)); | |
| 399 | + _undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined)); | |
| 398 | 400 | |
| 399 | − //V8ScriptValue undefined = v8::UniquePersistent<v8::Value>(_v8Isolate,v8::Undefined(_v8Isolate)); | |
| 400 | − //_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(undefined))); | |
| 401 | − V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate)); | |
| 402 | − _undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined)); | |
| 401 | + registerSystemTypes(); | |
| 403 | 402 | |
| 404 | − // V8TODO: | |
| 405 | − //QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND); | |
| 403 | + // V8TODO: dispose of isolate on ScriptEngineV8 destruction | |
| 404 | + //v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate)); | |
| 405 | + //_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null))); | |
| 406 | + | |
| 407 | + //V8ScriptValue undefined = v8::UniquePersistent<v8::Value>(_v8Isolate,v8::Undefined(_v8Isolate)); | |
| 408 | + //_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(undefined))); | |
| 409 | + | |
| 410 | + // V8TODO: | |
| 411 | + //QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND); | |
| 412 | + } | |
| 406 | 413 | |
| 407 | 414 | //_currentThread = QThread::currentThread(); |
| 408 | 415 | |
| @@ -514,6 +521,8 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) · 105 unmodified lines | ||
| 514 | 521 | } |
| 515 | 522 | |
| 516 | 523 | void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) { |
| 524 | + //if (QThread::currentThread() != ) { | |
| 525 | + //} | |
| 517 | 526 | if (QThread::currentThread() != thread()) { |
| 518 | 527 | #ifdef THREAD_DEBUGGING |
| 519 | 528 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerFunction() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] name:" << name; |
| @@ -556,7 +565,7 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name · 36 unmodified lines | ||
| 556 | 565 | v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); |
| 557 | 566 | ScriptValue object = globalObject().property(parent); |
| 558 | 567 | if (object.isValid()) { |
| 559 | − ScriptValue scriptFun = ScriptEngine::newFunction(functionSignature, numArguments); | |
| 568 | + ScriptValue scriptFun = newFunction(functionSignature, numArguments); | |
| 560 | 569 | object.setProperty(name, scriptFun); |
| 561 | 570 | } |
| 562 | 571 | } |
| @@ -580,20 +589,71 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun · 17 unmodified lines | ||
| 580 | 589 | #endif |
| 581 | 590 | |
| 582 | 591 | v8::HandleScope handleScope(_v8Isolate); |
| 583 | − v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); | |
| 592 | + v8::Context::Scope contextScope(getContext()); | |
| 593 | + | |
| 594 | + /*auto getterFunction = [](v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
| 595 | + //V8TODO: is using GetCurrentContext ok, or context wrapper needs to be added? | |
| 596 | + v8::HandleScope handleScope(info.GetIsolate()); | |
| 597 | + auto context = info.GetIsolate()->GetCurrentContext(); | |
| 598 | + v8::Context::Scope contextScope(context); | |
| 599 | + auto object = v8::Local<v8::Object>::Cast(info.Data()); | |
| 600 | + Q_ASSERT(object->InternalFieldCount() == 2); | |
| 601 | + auto function = reinterpret_cast<ScriptEngine::FunctionSignature> | |
| 602 | + (object->GetAlignedPointerFromInternalField(0)); | |
| 603 | + ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*> | |
| 604 | + (object->GetAlignedPointerFromInternalField(1)); | |
| 605 | + ScriptContextV8Wrapper scriptContext(scriptEngine, &info); | |
| 606 | + //V8TODO: this scriptContext needs to have FunctionCallbackInfo added | |
| 607 | + ScriptValue result = function(&scriptContext, scriptEngine); | |
| 608 | + ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result); | |
| 609 | + info.GetReturnValue().Set(unwrapped->toV8Value().constGet()); | |
| 610 | + }; | |
| 611 | + auto setterFunction = [](v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
| 612 | + //V8TODO: is using GetCurrentContext ok, or context wrapper needs to be added? | |
| 613 | + v8::HandleScope handleScope(info.GetIsolate()); | |
| 614 | + auto context = info.GetIsolate()->GetCurrentContext(); | |
| 615 | + v8::Context::Scope contextScope(context); | |
| 616 | + auto object = v8::Local<v8::Object>::Cast(info.Data()); | |
| 617 | + Q_ASSERT(object->InternalFieldCount() == 2); | |
| 618 | + auto function = reinterpret_cast<ScriptEngine::FunctionSignature> | |
| 619 | + (object->GetAlignedPointerFromInternalField(0)); | |
| 620 | + ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*> | |
| 621 | + (object->GetAlignedPointerFromInternalField(1)); | |
| 622 | + ScriptContextV8Wrapper scriptContext(scriptEngine, &info); | |
| 623 | + //V8TODO: this scriptContext needs to have FunctionCallbackInfo added | |
| 624 | + ScriptValue result = function(&scriptContext, scriptEngine); | |
| 625 | + ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result); | |
| 626 | + };*/ | |
| 584 | 627 | |
| 585 | 628 | ScriptValue setterFunction = newFunction(setter, 1); |
| 586 | 629 | ScriptValue getterFunction = newFunction(getter); |
| 630 | + V8ScriptValue unwrappedGetter = ScriptValueV8Wrapper::fullUnwrap(this, setterFunction); | |
| 631 | + V8ScriptValue unwrappedSetter = ScriptValueV8Wrapper::fullUnwrap(this, getterFunction); | |
| 632 | + v8::PropertyDescriptor propertyDescriptor(unwrappedGetter.get(), unwrappedSetter.get()); | |
| 587 | 633 | |
| 634 | + //V8TODO: Getters/setters are probably done in a different way in V8. Maybe object template is needed? | |
| 588 | 635 | if (!parent.isNull() && !parent.isEmpty()) { |
| 589 | − ScriptValue object = ScriptEngine::globalObject().property(parent); | |
| 636 | + ScriptValue object = globalObject().property(parent); | |
| 590 | 637 | if (object.isValid()) { |
| 591 | − object.setProperty(name, setterFunction, ScriptValue::PropertySetter); | |
| 592 | − object.setProperty(name, getterFunction, ScriptValue::PropertyGetter); | |
| 638 | + V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object); | |
| 639 | + Q_ASSERT(v8parent.get()->IsObject()); | |
| 640 | + v8::Local<v8::Object> v8object = v8::Local<v8::Object>::Cast(v8parent.get()); | |
| 641 | + v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked(); | |
| 642 | + if(!v8object->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) { | |
| 643 | + qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \"" << parent << "\""; | |
| 644 | + } | |
| 645 | + //object.setProperty(name, setterFunction, ScriptValue::PropertySetter); | |
| 646 | + //object.setProperty(name, getterFunction, ScriptValue::PropertyGetter); | |
| 647 | + } else { | |
| 648 | + qCDebug(scriptengine) << "Parent object \"" << parent << "\" for registerGetterSetter \"" << name << "\" is not valid: "; | |
| 593 | 649 | } |
| 594 | 650 | } else { |
| 595 | − globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter); | |
| 596 | − globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter); | |
| 651 | + v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked(); | |
| 652 | + if(!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) { | |
| 653 | + qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object"; | |
| 654 | + } | |
| 655 | + //globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter); | |
| 656 | + //globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter); | |
| 597 | 657 | } |
| 598 | 658 | } |
| 599 | 659 | |
| @@ -783,8 +843,9 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 183 unmodified lines | ||
| 783 | 843 | Q_ASSERT(tryCatchRun.HasCaught()); |
| 784 | 844 | auto runError = tryCatchRun.Message(); |
| 785 | 845 | ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get()))); |
| 786 | − raiseException(errorValue); | |
| 787 | − maybeEmitUncaughtException("evaluate"); | |
| 846 | + //V8TODO | |
| 847 | + //raiseException(errorValue); | |
| 848 | + //maybeEmitUncaughtException("evaluate"); | |
| 788 | 849 | return errorValue; |
| 789 | 850 | } |
| 790 | 851 | V8ScriptValue resultValue(_v8Isolate, result); |
| @@ -1016,8 +1077,8 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 225 unmodified lines | ||
| 1016 | 1077 | }*/ |
| 1017 | 1078 | //_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), localCtx); |
| 1018 | 1079 | if (!_currContext) { |
| 1019 | − // I'm not sure how to do this without discardin const | |
| 1020 | − _currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), getConstContext()); | |
| 1080 | + // I'm not sure how to do this without discarding const | |
| 1081 | + _currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this)); | |
| 1021 | 1082 | } |
| 1022 | 1083 | return _currContext.get(); |
| 1023 | 1084 | } |
| @@ -1025,11 +1086,13 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 1 unmodified line | ||
| 1025 | 1086 | bool ScriptEngineV8::hasUncaughtException() const { |
| 1026 | 1087 | //V8TODO |
| 1027 | 1088 | //return QScriptEngine::hasUncaughtException(); |
| 1089 | + return false; | |
| 1028 | 1090 | } |
| 1029 | 1091 | |
| 1030 | 1092 | bool ScriptEngineV8::isEvaluating() const { |
| 1031 | 1093 | //V8TODO |
| 1032 | 1094 | //return QScriptEngine::isEvaluating(); |
| 1095 | + return false; | |
| 1033 | 1096 | } |
| 1034 | 1097 | |
| 1035 | 1098 | ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int length) { |
| @@ -1050,13 +1113,14 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 14 unmodified lines | ||
| 1050 | 1113 | auto context = info.GetIsolate()->GetCurrentContext(); |
| 1051 | 1114 | v8::Context::Scope contextScope(context); |
| 1052 | 1115 | auto object = v8::Local<v8::Object>::Cast(info.Data()); |
| 1116 | + Q_ASSERT(object->InternalFieldCount() == 2); | |
| 1053 | 1117 | auto function = reinterpret_cast<ScriptEngine::FunctionSignature> |
| 1054 | 1118 | (object->GetAlignedPointerFromInternalField(0)); |
| 1055 | − ScriptContext *scriptContext = reinterpret_cast<ScriptContext*> | |
| 1056 | − (object->GetAlignedPointerFromInternalField(1));; | |
| 1057 | 1119 | ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*> |
| 1058 | − (object->GetAlignedPointerFromInternalField(2));; | |
| 1059 | − ScriptValue result = function(scriptContext, scriptEngine); | |
| 1120 | + (object->GetAlignedPointerFromInternalField(1)); | |
| 1121 | + ScriptContextV8Wrapper scriptContext(scriptEngine, &info); | |
| 1122 | + //V8TODO: this scriptContext needs to have FunctionCallbackInfo added | |
| 1123 | + ScriptValue result = function(&scriptContext, scriptEngine); | |
| 1060 | 1124 | ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result); |
| 1061 | 1125 | info.GetReturnValue().Set(unwrapped->toV8Value().constGet()); |
| 1062 | 1126 | }; |
| @@ -1066,11 +1130,10 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 3 unmodified lines | ||
| 1066 | 1130 | v8::HandleScope handleScope(_v8Isolate); |
| 1067 | 1131 | v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate)); |
| 1068 | 1132 | auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate); |
| 1069 | − functionDataTemplate->SetInternalFieldCount(3); | |
| 1133 | + functionDataTemplate->SetInternalFieldCount(2); | |
| 1070 | 1134 | auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked(); |
| 1071 | 1135 | functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun)); |
| 1072 | 1136 | functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this)); |
| 1073 | − functionData->SetAlignedPointerInInternalField(2, reinterpret_cast<void*>(currentContext())); | |
| 1074 | 1137 | //functionData->SetInternalField(3, v8::Null(_v8Isolate)); |
| 1075 | 1138 | auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked(); |
| 1076 | 1139 | //auto functionObjectTemplate = functionTemplate->InstanceTemplate(); |
| @@ -1138,10 +1201,12 @@ int ScriptEngineV8::uncaughtExceptionLineNumber() const { · 61 unmodified lines | ||
| 1138 | 1201 | |
| 1139 | 1202 | bool ScriptEngineV8::raiseException(const ScriptValue& exception) { |
| 1140 | 1203 | //V8TODO |
| 1141 | − Q_ASSERT(false); | |
| 1204 | + //Q_ASSERT(false); | |
| 1205 | + qCritical() << "Script exception occured: " << exception.toString(); | |
| 1142 | 1206 | /*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(exception); |
| 1143 | 1207 | V8ScriptValue qException = unwrapped ? unwrapped->toV8Value() : QScriptEngine::newVariant(exception.toVariant()); |
| 1144 | 1208 | return raiseException(qException);*/ |
| 1209 | + return false; | |
| 1145 | 1210 | } |
| 1146 | 1211 | |
| 1147 | 1212 | ScriptValue ScriptEngineV8::create(int type, const void* ptr) { |
| @@ -1171,4 +1236,5 @@ QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) { · 23 unmodified lines | ||
| 1171 | 1236 | } |
| 1172 | 1237 | |
| 1173 | 1238 | return var; |
| 1239 | + return QVariant(); | |
| 1174 | 1240 | } |