History

Script engine new function fixes

ksuprynowicz committed 4 years ago

Commit 58a22151 parent a4c69306 files · +199 −98Browse files

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

Unified · Split

libraries/script-engine/src/v8/ScriptEngineV8.cpp+107−41
@@ -294,7 +294,7 @@ ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8Scri · 293 unmodified lines
294 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));294 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
295 auto lambda = new Lambda(this, operation, data);295 auto lambda = new Lambda(this, operation, data);
296 auto object = newQObject(lambda, ownership);296 auto object = newQObject(lambda, ownership);
297 //V8TODO?297 //V8TODO - I'm not sure if this works
298 auto call = object.property("call");298 auto call = object.property("call");
299 call.setPrototype(object); // context->callee().prototype() === Lambda QObject299 call.setPrototype(object); // context->callee().prototype() === Lambda QObject
300 call.setData(ScriptValue(new ScriptValueV8Wrapper(this, data))); // context->callee().data() will === data param300 call.setData(ScriptValue(new ScriptValueV8Wrapper(this, data))); // context->callee().data() will === data param
@@ -334,8 +334,10 @@ V8ScriptValue Lambda::call() { · 33 unmodified lines
334 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {334 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
335 return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));335 return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
336 }336 }
337 return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));337 // V8TODO: it needs to be done in entirely different way for V8
338 // V8TODO: something is obviously wrong here, there's no call at all?338 Q_ASSERT(false);
339 //return _operation(_engine->getContext(), _engine);
340 //return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
339 //return operation(static_cast<QScriptEngine*>(engine)->currentContext(), engine);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 v8::V8::Initialize();381 v8::V8::Initialize();
380 } );382 } );
381 _v8InitMutex.unlock();383 _v8InitMutex.unlock();
382 v8::Isolate::CreateParams isolateParams;384 {
383 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();385 v8::Isolate::CreateParams isolateParams;
384 _v8Isolate = v8::Isolate::New(isolateParams);386 isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
385 _v8Isolate->Enter();387 _v8Isolate = v8::Isolate::New(isolateParams);
386 v8::HandleScope handleScope(_v8Isolate);388 _v8Isolate->Enter();
387 v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);389 v8::HandleScope handleScope(_v8Isolate);
388 Q_ASSERT(!context.IsEmpty());390 v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);
389 _v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context);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 destruction398 V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate));
394 //v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate));399 _undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined));
395 //_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null)));
396 V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate));
397 _nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
398 400
399 //V8ScriptValue undefined = v8::UniquePersistent<v8::Value>(_v8Isolate,v8::Undefined(_v8Isolate));401 registerSystemTypes();
400 //_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(undefined)));
401 V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate));
402 _undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined));
403 402
404 // V8TODO: 403 // V8TODO: dispose of isolate on ScriptEngineV8 destruction
405 //QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND);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 //_currentThread = QThread::currentThread();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
516void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {523void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
524 //if (QThread::currentThread() != ) {
525 //}
517 if (QThread::currentThread() != thread()) {526 if (QThread::currentThread() != thread()) {
518#ifdef THREAD_DEBUGGING527#ifdef THREAD_DEBUGGING
519 qCDebug(scriptengine) << "*** WARNING *** ScriptEngineV8::registerFunction() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] name:" << name;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 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));565 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
557 ScriptValue object = globalObject().property(parent);566 ScriptValue object = globalObject().property(parent);
558 if (object.isValid()) {567 if (object.isValid()) {
559 ScriptValue scriptFun = ScriptEngine::newFunction(functionSignature, numArguments);568 ScriptValue scriptFun = newFunction(functionSignature, numArguments);
560 object.setProperty(name, scriptFun);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#endif589#endif
581 590
582 v8::HandleScope handleScope(_v8Isolate);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 ScriptValue setterFunction = newFunction(setter, 1);628 ScriptValue setterFunction = newFunction(setter, 1);
586 ScriptValue getterFunction = newFunction(getter);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 if (!parent.isNull() && !parent.isEmpty()) {635 if (!parent.isNull() && !parent.isEmpty()) {
589 ScriptValue object = ScriptEngine::globalObject().property(parent);636 ScriptValue object = globalObject().property(parent);
590 if (object.isValid()) {637 if (object.isValid()) {
591 object.setProperty(name, setterFunction, ScriptValue::PropertySetter);638 V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object);
592 object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);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 } else {650 } else {
595 globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);651 v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
596 globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);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 Q_ASSERT(tryCatchRun.HasCaught());843 Q_ASSERT(tryCatchRun.HasCaught());
784 auto runError = tryCatchRun.Message();844 auto runError = tryCatchRun.Message();
785 ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));845 ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
786 raiseException(errorValue);846 //V8TODO
787 maybeEmitUncaughtException("evaluate");847 //raiseException(errorValue);
848 //maybeEmitUncaughtException("evaluate");
788 return errorValue;849 return errorValue;
789 }850 }
790 V8ScriptValue resultValue(_v8Isolate, result);851 V8ScriptValue resultValue(_v8Isolate, result);
@@ -1016,8 +1077,8 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 225 unmodified lines
1016 }*/1077 }*/
1017 //_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), localCtx);1078 //_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), localCtx);
1018 if (!_currContext) {1079 if (!_currContext) {
1019 // I'm not sure how to do this without discardin const1080 // I'm not sure how to do this without discarding const
1020 _currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), getConstContext());1081 _currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this));
1021 }1082 }
1022 return _currContext.get();1083 return _currContext.get();
1023}1084}
@@ -1025,11 +1086,13 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 1 unmodified line
1025bool ScriptEngineV8::hasUncaughtException() const {1086bool ScriptEngineV8::hasUncaughtException() const {
1026 //V8TODO1087 //V8TODO
1027 //return QScriptEngine::hasUncaughtException();1088 //return QScriptEngine::hasUncaughtException();
1089 return false;
1028}1090}
1029 1091
1030bool ScriptEngineV8::isEvaluating() const {1092bool ScriptEngineV8::isEvaluating() const {
1031 //V8TODO1093 //V8TODO
1032 //return QScriptEngine::isEvaluating();1094 //return QScriptEngine::isEvaluating();
1095 return false;
1033}1096}
1034 1097
1035ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int length) {1098ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int length) {
@@ -1050,13 +1113,14 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 14 unmodified lines
1050 auto context = info.GetIsolate()->GetCurrentContext();1113 auto context = info.GetIsolate()->GetCurrentContext();
1051 v8::Context::Scope contextScope(context);1114 v8::Context::Scope contextScope(context);
1052 auto object = v8::Local<v8::Object>::Cast(info.Data());1115 auto object = v8::Local<v8::Object>::Cast(info.Data());
1116 Q_ASSERT(object->InternalFieldCount() == 2);
1053 auto function = reinterpret_cast<ScriptEngine::FunctionSignature>1117 auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
1054 (object->GetAlignedPointerFromInternalField(0));1118 (object->GetAlignedPointerFromInternalField(0));
1055 ScriptContext *scriptContext = reinterpret_cast<ScriptContext*>
1056 (object->GetAlignedPointerFromInternalField(1));;
1057 ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>1119 ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
1058 (object->GetAlignedPointerFromInternalField(2));;1120 (object->GetAlignedPointerFromInternalField(1));
1059 ScriptValue result = function(scriptContext, scriptEngine);1121 ScriptContextV8Wrapper scriptContext(scriptEngine, &info);
1122 //V8TODO: this scriptContext needs to have FunctionCallbackInfo added
1123 ScriptValue result = function(&scriptContext, scriptEngine);
1060 ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);1124 ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
1061 info.GetReturnValue().Set(unwrapped->toV8Value().constGet());1125 info.GetReturnValue().Set(unwrapped->toV8Value().constGet());
1062 };1126 };
@@ -1066,11 +1130,10 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 3 unmodified lines
1066 v8::HandleScope handleScope(_v8Isolate);1130 v8::HandleScope handleScope(_v8Isolate);
1067 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));1131 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
1068 auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);1132 auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);
1069 functionDataTemplate->SetInternalFieldCount(3);1133 functionDataTemplate->SetInternalFieldCount(2);
1070 auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();1134 auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();
1071 functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun));1135 functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun));
1072 functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));1136 functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
1073 functionData->SetAlignedPointerInInternalField(2, reinterpret_cast<void*>(currentContext()));
1074 //functionData->SetInternalField(3, v8::Null(_v8Isolate));1137 //functionData->SetInternalField(3, v8::Null(_v8Isolate));
1075 auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked();1138 auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked();
1076 //auto functionObjectTemplate = functionTemplate->InstanceTemplate();1139 //auto functionObjectTemplate = functionTemplate->InstanceTemplate();
@@ -1138,10 +1201,12 @@ int ScriptEngineV8::uncaughtExceptionLineNumber() const { · 61 unmodified lines
1138 1201
1139bool ScriptEngineV8::raiseException(const ScriptValue& exception) {1202bool ScriptEngineV8::raiseException(const ScriptValue& exception) {
1140 //V8TODO1203 //V8TODO
1141 Q_ASSERT(false);1204 //Q_ASSERT(false);
1205 qCritical() << "Script exception occured: " << exception.toString();
1142 /*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(exception);1206 /*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(exception);
1143 V8ScriptValue qException = unwrapped ? unwrapped->toV8Value() : QScriptEngine::newVariant(exception.toVariant());1207 V8ScriptValue qException = unwrapped ? unwrapped->toV8Value() : QScriptEngine::newVariant(exception.toVariant());
1144 return raiseException(qException);*/1208 return raiseException(qException);*/
1209 return false;
1145}1210}
1146 1211
1147ScriptValue ScriptEngineV8::create(int type, const void* ptr) {1212ScriptValue 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 return var;1238 return var;
1239 return QVariant();
1174}1240}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t