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
294294 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
295295 auto lambda = new Lambda(this, operation, data);
296296 auto object = newQObject(lambda, ownership);
297− //V8TODO?
297+ //V8TODO - I'm not sure if this works
298298 auto call = object.property("call");
299299 call.setPrototype(object); // context->callee().prototype() === Lambda QObject
300300 call.setData(ScriptValue(new ScriptValueV8Wrapper(this, data))); // context->callee().data() will === data param
@@ -334,8 +334,10 @@ V8ScriptValue Lambda::call() { · 33 unmodified lines
334334 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
335335 return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
336336 }
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()));
339341 //return operation(static_cast<QScriptEngine*>(engine)->currentContext(), engine);
340342 }
341343
@@ -379,30 +381,35 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) : · 37 unmodified lines
379381 v8::V8::Initialize();
380382 } );
381383 _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);
390394
391− registerSystemTypes();
395+ V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate));
396+ _nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
392397
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));
398400
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();
403402
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+ }
406413
407414 //_currentThread = QThread::currentThread();
408415
@@ -514,6 +521,8 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object) · 105 unmodified lines
514521 }
515522
516523 void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
524+ //if (QThread::currentThread() != ) {
525+ //}
517526 if (QThread::currentThread() != thread()) {
518527 #ifdef THREAD_DEBUGGING
519528 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
556565 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
557566 ScriptValue object = globalObject().property(parent);
558567 if (object.isValid()) {
559− ScriptValue scriptFun = ScriptEngine::newFunction(functionSignature, numArguments);
568+ ScriptValue scriptFun = newFunction(functionSignature, numArguments);
560569 object.setProperty(name, scriptFun);
561570 }
562571 }
@@ -580,20 +589,71 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun · 17 unmodified lines
580589 #endif
581590
582591 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+ };*/
584627
585628 ScriptValue setterFunction = newFunction(setter, 1);
586629 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());
587633
634+ //V8TODO: Getters/setters are probably done in a different way in V8. Maybe object template is needed?
588635 if (!parent.isNull() && !parent.isEmpty()) {
589− ScriptValue object = ScriptEngine::globalObject().property(parent);
636+ ScriptValue object = globalObject().property(parent);
590637 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: ";
593649 }
594650 } 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);
597657 }
598658 }
599659
@@ -783,8 +843,9 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 183 unmodified lines
783843 Q_ASSERT(tryCatchRun.HasCaught());
784844 auto runError = tryCatchRun.Message();
785845 ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
786− raiseException(errorValue);
787− maybeEmitUncaughtException("evaluate");
846+ //V8TODO
847+ //raiseException(errorValue);
848+ //maybeEmitUncaughtException("evaluate");
788849 return errorValue;
789850 }
790851 V8ScriptValue resultValue(_v8Isolate, result);
@@ -1016,8 +1077,8 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 225 unmodified lines
10161077 }*/
10171078 //_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), localCtx);
10181079 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));
10211082 }
10221083 return _currContext.get();
10231084 }
@@ -1025,11 +1086,13 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 1 unmodified line
10251086 bool ScriptEngineV8::hasUncaughtException() const {
10261087 //V8TODO
10271088 //return QScriptEngine::hasUncaughtException();
1089+ return false;
10281090 }
10291091
10301092 bool ScriptEngineV8::isEvaluating() const {
10311093 //V8TODO
10321094 //return QScriptEngine::isEvaluating();
1095+ return false;
10331096 }
10341097
10351098 ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int length) {
@@ -1050,13 +1113,14 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 14 unmodified lines
10501113 auto context = info.GetIsolate()->GetCurrentContext();
10511114 v8::Context::Scope contextScope(context);
10521115 auto object = v8::Local<v8::Object>::Cast(info.Data());
1116+ Q_ASSERT(object->InternalFieldCount() == 2);
10531117 auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
10541118 (object->GetAlignedPointerFromInternalField(0));
1055− ScriptContext *scriptContext = reinterpret_cast<ScriptContext*>
1056− (object->GetAlignedPointerFromInternalField(1));;
10571119 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);
10601124 ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
10611125 info.GetReturnValue().Set(unwrapped->toV8Value().constGet());
10621126 };
@@ -1066,11 +1130,10 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int · 3 unmodified lines
10661130 v8::HandleScope handleScope(_v8Isolate);
10671131 v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
10681132 auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);
1069− functionDataTemplate->SetInternalFieldCount(3);
1133+ functionDataTemplate->SetInternalFieldCount(2);
10701134 auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();
10711135 functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun));
10721136 functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
1073− functionData->SetAlignedPointerInInternalField(2, reinterpret_cast<void*>(currentContext()));
10741137 //functionData->SetInternalField(3, v8::Null(_v8Isolate));
10751138 auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked();
10761139 //auto functionObjectTemplate = functionTemplate->InstanceTemplate();
@@ -1138,10 +1201,12 @@ int ScriptEngineV8::uncaughtExceptionLineNumber() const { · 61 unmodified lines
11381201
11391202 bool ScriptEngineV8::raiseException(const ScriptValue& exception) {
11401203 //V8TODO
1141− Q_ASSERT(false);
1204+ //Q_ASSERT(false);
1205+ qCritical() << "Script exception occured: " << exception.toString();
11421206 /*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(exception);
11431207 V8ScriptValue qException = unwrapped ? unwrapped->toV8Value() : QScriptEngine::newVariant(exception.toVariant());
11441208 return raiseException(qException);*/
1209+ return false;
11451210 }
11461211
11471212 ScriptValue ScriptEngineV8::create(int type, const void* ptr) {
@@ -1171,4 +1236,5 @@ QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) { · 23 unmodified lines
11711236 }
11721237
11731238 return var;
1239+ return QVariant();
11741240 }

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