mirror of
https://github.com/overte-org/overte.git
synced 2025-07-29 21:07:31 +02:00
More fixes for V8
This commit is contained in:
parent
dc9044b3b3
commit
797d92d5dc
9 changed files with 212 additions and 70 deletions
|
@ -147,11 +147,18 @@ ScriptValue ScriptContextV8Wrapper::thisObject() const {
|
||||||
|
|
||||||
ScriptValue ScriptContextV8Wrapper::throwError(const QString& text) {
|
ScriptValue ScriptContextV8Wrapper::throwError(const QString& text) {
|
||||||
auto isolate = _engine->getIsolate();
|
auto isolate = _engine->getIsolate();
|
||||||
Q_ASSERT(isolate->IsCurrent());
|
// V8TODO: I have no idea how to do this yet because it happens on another thread
|
||||||
|
if(isolate->IsCurrent()) {
|
||||||
v8::HandleScope handleScope(isolate);
|
v8::HandleScope handleScope(isolate);
|
||||||
v8::Context::Scope contextScope(_engine->getContext());
|
v8::Context::Scope contextScope(_engine->getContext());
|
||||||
V8ScriptValue result(_engine->getIsolate(), _engine->getIsolate()->ThrowError(v8::String::NewFromUtf8(_engine->getIsolate(), text.toStdString().c_str()).ToLocalChecked()));
|
V8ScriptValue result(_engine->getIsolate(),
|
||||||
|
_engine->getIsolate()->ThrowError(
|
||||||
|
v8::String::NewFromUtf8(_engine->getIsolate(), text.toStdString().c_str()).ToLocalChecked()));
|
||||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||||
|
} else {
|
||||||
|
qWarning() << "throwError on a different thread not implemented yet, error value: " << text;
|
||||||
|
return _engine->undefinedValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValue ScriptContextV8Wrapper::throwValue(const ScriptValue& value) {
|
ScriptValue ScriptContextV8Wrapper::throwValue(const ScriptValue& value) {
|
||||||
|
|
|
@ -370,7 +370,7 @@ v8::Platform* ScriptEngineV8::getV8Platform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
||||||
_scriptManager(scriptManager)
|
_scriptManager(scriptManager), _isEvaluating(false)
|
||||||
//V8TODO
|
//V8TODO
|
||||||
//_arrayBufferClass(new ArrayBufferClass(this))
|
//_arrayBufferClass(new ArrayBufferClass(this))
|
||||||
{
|
{
|
||||||
|
@ -514,6 +514,14 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object)
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name;
|
qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name;
|
||||||
#endif
|
#endif
|
||||||
|
bool is_isolate_exit_needed = false;
|
||||||
|
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||||
|
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||||
|
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||||
|
_v8Isolate->Enter();
|
||||||
|
is_isolate_exit_needed = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
Q_ASSERT(_v8Isolate->IsCurrent());
|
Q_ASSERT(_v8Isolate->IsCurrent());
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
|
@ -530,6 +538,11 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (is_isolate_exit_needed) {
|
||||||
|
_v8Isolate->Exit();
|
||||||
|
_v8Locker.reset(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
|
void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
|
||||||
//if (QThread::currentThread() != ) {
|
//if (QThread::currentThread() != ) {
|
||||||
|
@ -548,6 +561,14 @@ void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::Functio
|
||||||
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name;
|
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool is_isolate_exit_needed = false;
|
||||||
|
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||||
|
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||||
|
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||||
|
_v8Isolate->Enter();
|
||||||
|
is_isolate_exit_needed = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
//auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet();
|
//auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet();
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
|
@ -556,6 +577,11 @@ void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::Functio
|
||||||
//getContext()->Global().Set();
|
//getContext()->Global().Set();
|
||||||
globalObject().setProperty(name, scriptFun);
|
globalObject().setProperty(name, scriptFun);
|
||||||
}
|
}
|
||||||
|
if (is_isolate_exit_needed) {
|
||||||
|
_v8Isolate->Exit();
|
||||||
|
_v8Locker.reset(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngineV8::registerFunction(const QString& parent, const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
|
void ScriptEngineV8::registerFunction(const QString& parent, const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
|
@ -572,6 +598,14 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name
|
||||||
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name;
|
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool is_isolate_exit_needed = false;
|
||||||
|
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||||
|
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||||
|
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||||
|
_v8Isolate->Enter();
|
||||||
|
is_isolate_exit_needed = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
ScriptValue object = globalObject().property(parent);
|
ScriptValue object = globalObject().property(parent);
|
||||||
|
@ -580,6 +614,11 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name
|
||||||
object.setProperty(name, scriptFun);
|
object.setProperty(name, scriptFun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (is_isolate_exit_needed) {
|
||||||
|
_v8Isolate->Exit();
|
||||||
|
_v8Locker.reset(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::FunctionSignature getter,
|
void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::FunctionSignature getter,
|
||||||
ScriptEngine::FunctionSignature setter, const QString& parent) {
|
ScriptEngine::FunctionSignature setter, const QString& parent) {
|
||||||
|
@ -599,6 +638,14 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
|
||||||
qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent;
|
qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool is_isolate_exit_needed = false;
|
||||||
|
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||||
|
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||||
|
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||||
|
_v8Isolate->Enter();
|
||||||
|
is_isolate_exit_needed = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(getContext());
|
v8::Context::Scope contextScope(getContext());
|
||||||
|
|
||||||
|
@ -649,17 +696,21 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
|
||||||
V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object);
|
V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object);
|
||||||
Q_ASSERT(v8parent.get()->IsObject());
|
Q_ASSERT(v8parent.get()->IsObject());
|
||||||
v8::Local<v8::Object> v8object = v8::Local<v8::Object>::Cast(v8parent.get());
|
v8::Local<v8::Object> v8object = v8::Local<v8::Object>::Cast(v8parent.get());
|
||||||
v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
|
v8::Local<v8::String> v8propertyName =
|
||||||
|
v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
|
||||||
if (!v8object->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
|
if (!v8object->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
|
||||||
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \"" << parent << "\"";
|
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \""
|
||||||
|
<< parent << "\"";
|
||||||
}
|
}
|
||||||
//object.setProperty(name, setterFunction, ScriptValue::PropertySetter);
|
//object.setProperty(name, setterFunction, ScriptValue::PropertySetter);
|
||||||
//object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
//object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(scriptengine) << "Parent object \"" << parent << "\" for registerGetterSetter \"" << name << "\" is not valid: ";
|
qCDebug(scriptengine) << "Parent object \"" << parent << "\" for registerGetterSetter \"" << name
|
||||||
|
<< "\" is not valid: ";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
|
v8::Local<v8::String> v8propertyName =
|
||||||
|
v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
|
||||||
if (!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
|
if (!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
|
||||||
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object";
|
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object";
|
||||||
}
|
}
|
||||||
|
@ -667,6 +718,11 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
|
||||||
//globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
//globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (is_isolate_exit_needed) {
|
||||||
|
_v8Isolate->Exit();
|
||||||
|
_v8Locker.reset(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
const ScriptProgramPointer& _program) {
|
const ScriptProgramPointer& _program) {
|
||||||
|
@ -674,10 +730,13 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
|
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(!isEvaluating());
|
||||||
|
_isEvaluating = true;
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
|
ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
|
||||||
if (unwrappedProgram == nullptr) {
|
if (unwrappedProgram == nullptr) {
|
||||||
|
_isEvaluating = false;
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
const V8ScriptProgram& program = unwrappedProgram->toV8Value();
|
const V8ScriptProgram& program = unwrappedProgram->toV8Value();
|
||||||
|
@ -687,10 +746,12 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
|
|
||||||
ScriptValueV8Wrapper* unwrappedClosure = ScriptValueV8Wrapper::unwrap(_closure);
|
ScriptValueV8Wrapper* unwrappedClosure = ScriptValueV8Wrapper::unwrap(_closure);
|
||||||
if (unwrappedClosure == nullptr) {
|
if (unwrappedClosure == nullptr) {
|
||||||
|
_isEvaluating = false;
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
const V8ScriptValue& closure = unwrappedClosure->toV8Value();
|
const V8ScriptValue& closure = unwrappedClosure->toV8Value();
|
||||||
if (!closure.constGet()->IsObject()) {
|
if (!closure.constGet()->IsObject()) {
|
||||||
|
_isEvaluating = false;
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
const v8::Local<v8::Object> closureObject = v8::Local<v8::Object>::Cast(closure.constGet());
|
const v8::Local<v8::Object> closureObject = v8::Local<v8::Object>::Cast(closure.constGet());
|
||||||
|
@ -698,6 +759,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
v8::Local<v8::Value> oldGlobal;
|
v8::Local<v8::Value> oldGlobal;
|
||||||
v8::Local<v8::Value> closureGlobal;
|
v8::Local<v8::Value> closureGlobal;
|
||||||
if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked()).ToLocal(&closureGlobal)) {
|
if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked()).ToLocal(&closureGlobal)) {
|
||||||
|
_isEvaluating = false;
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +783,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
v8::Local<v8::Value> thiz;
|
v8::Local<v8::Value> thiz;
|
||||||
// V8TODO: not sure if "this" doesn't exist or is empty in some cases
|
// V8TODO: not sure if "this" doesn't exist or is empty in some cases
|
||||||
if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked()).ToLocal(&thiz)) {
|
if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "this").ToLocalChecked()).ToLocal(&thiz)) {
|
||||||
|
_isEvaluating = false;
|
||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
//thiz = closure.property("this");
|
//thiz = closure.property("this");
|
||||||
|
@ -776,6 +839,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
//_v8Context.Get(_v8Isolate)->Enter();
|
//_v8Context.Get(_v8Isolate)->Enter();
|
||||||
|
_isEvaluating = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,6 +865,8 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
||||||
// Compile and check syntax
|
// Compile and check syntax
|
||||||
// V8TODO: Could these all be replaced with checkSyntax function from wrapper?
|
// V8TODO: Could these all be replaced with checkSyntax function from wrapper?
|
||||||
Q_ASSERT(!_v8Isolate->IsDead());
|
Q_ASSERT(!_v8Isolate->IsDead());
|
||||||
|
Q_ASSERT(!isEvaluating());
|
||||||
|
_isEvaluating = true;
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
v8::TryCatch tryCatch(getIsolate());
|
v8::TryCatch tryCatch(getIsolate());
|
||||||
|
@ -830,6 +896,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
||||||
auto err = makeError(newValue(errorMessage));
|
auto err = makeError(newValue(errorMessage));
|
||||||
raiseException(err);
|
raiseException(err);
|
||||||
maybeEmitUncaughtException("compile");
|
maybeEmitUncaughtException("compile");
|
||||||
|
_isEvaluating = false;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
qCDebug(scriptengine) << "Script compilation succesful: " << fileName;
|
qCDebug(scriptengine) << "Script compilation succesful: " << fileName;
|
||||||
|
@ -863,9 +930,11 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
||||||
//V8TODO
|
//V8TODO
|
||||||
//raiseException(errorValue);
|
//raiseException(errorValue);
|
||||||
//maybeEmitUncaughtException("evaluate");
|
//maybeEmitUncaughtException("evaluate");
|
||||||
|
_isEvaluating = false;
|
||||||
return errorValue;
|
return errorValue;
|
||||||
}
|
}
|
||||||
V8ScriptValue resultValue(_v8Isolate, result);
|
V8ScriptValue resultValue(_v8Isolate, result);
|
||||||
|
_isEvaluating = false;
|
||||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
|
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,6 +979,8 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
Q_ARG(const ScriptProgramPointer&, program));
|
Q_ARG(const ScriptProgramPointer&, program));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Q_ASSERT(!isEvaluating());
|
||||||
|
_isEvaluating = true;
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
||||||
|
@ -917,6 +988,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
auto err = makeError(newValue("could not unwrap program"));
|
auto err = makeError(newValue("could not unwrap program"));
|
||||||
raiseException(err);
|
raiseException(err);
|
||||||
maybeEmitUncaughtException("compile");
|
maybeEmitUncaughtException("compile");
|
||||||
|
_isEvaluating = false;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
|
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
|
||||||
|
@ -924,6 +996,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
auto err = makeError(newValue(syntaxCheck->errorMessage()));
|
auto err = makeError(newValue(syntaxCheck->errorMessage()));
|
||||||
raiseException(err);
|
raiseException(err);
|
||||||
maybeEmitUncaughtException("compile");
|
maybeEmitUncaughtException("compile");
|
||||||
|
_isEvaluating = false;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,9 +1018,11 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
||||||
raiseException(errorValue);
|
raiseException(errorValue);
|
||||||
maybeEmitUncaughtException("evaluate");
|
maybeEmitUncaughtException("evaluate");
|
||||||
|
_isEvaluating = false;
|
||||||
return errorValue;
|
return errorValue;
|
||||||
}
|
}
|
||||||
V8ScriptValue resultValue(_v8Isolate, result);
|
V8ScriptValue resultValue(_v8Isolate, result);
|
||||||
|
_isEvaluating = false;
|
||||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
|
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,6 +1094,8 @@ ScriptProgramPointer ScriptEngineV8::newProgram(const QString& sourceCode, const
|
||||||
//V8TODO: is it used between isolates?
|
//V8TODO: is it used between isolates?
|
||||||
//V8TODO: should it be compiled on creation?
|
//V8TODO: should it be compiled on creation?
|
||||||
//V8ScriptProgram result(sourceCode, fileName);
|
//V8ScriptProgram result(sourceCode, fileName);
|
||||||
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
|
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,8 +1209,8 @@ bool ScriptEngineV8::hasUncaughtException() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptEngineV8::isEvaluating() const {
|
bool ScriptEngineV8::isEvaluating() const {
|
||||||
//V8TODO
|
|
||||||
//return QScriptEngine::isEvaluating();
|
//return QScriptEngine::isEvaluating();
|
||||||
|
return _isEvaluating;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,7 @@ protected:
|
||||||
|
|
||||||
//V8TODO
|
//V8TODO
|
||||||
//ArrayBufferClass* _arrayBufferClass;
|
//ArrayBufferClass* _arrayBufferClass;
|
||||||
|
bool _isEvaluating;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lambda helps create callable V8ScriptValues out of std::functions:
|
// Lambda helps create callable V8ScriptValues out of std::functions:
|
||||||
|
|
|
@ -433,6 +433,48 @@ bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& de
|
||||||
case QMetaType::QObjectStar:
|
case QMetaType::QObjectStar:
|
||||||
dest = QVariant::fromValue(ScriptObjectV8Proxy::unwrap(v8Val));
|
dest = QVariant::fromValue(ScriptObjectV8Proxy::unwrap(v8Val));
|
||||||
break;
|
break;
|
||||||
|
case QMetaType::QVariant:
|
||||||
|
if (val->IsUndefined()) {
|
||||||
|
dest = QVariant();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val->IsNull()) {
|
||||||
|
dest = QVariant::fromValue(nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val->IsBoolean()) {
|
||||||
|
//V8TODO is it right isolate? What if value from different script engine is used here
|
||||||
|
dest = QVariant::fromValue(val->BooleanValue(_v8Isolate));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val->IsString()) {
|
||||||
|
//V8TODO is it right context? What if value from different script engine is used here
|
||||||
|
v8::String::Utf8Value string(_v8Isolate, val);
|
||||||
|
Q_ASSERT(*string != nullptr);
|
||||||
|
dest = QVariant::fromValue(QString(*string));
|
||||||
|
//dest = QVariant::fromValue(val->ToString(_v8Context.Get(_v8Isolate)).ToLocalChecked()->);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val->IsNumber()) {
|
||||||
|
dest = QVariant::fromValue(val->ToNumber(_v8Context.Get(_v8Isolate)).ToLocalChecked()->Value());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QObject* obj = ScriptObjectV8Proxy::unwrap(v8Val);
|
||||||
|
if (obj) {
|
||||||
|
dest = QVariant::fromValue(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QVariant var = ScriptVariantV8Proxy::unwrap(v8Val);
|
||||||
|
if (var.isValid()) {
|
||||||
|
dest = var;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// V8TODO maybe export as JSON and then convert from JSON to QVariant?
|
||||||
|
Q_ASSERT(false);
|
||||||
default:
|
default:
|
||||||
// check to see if this is a pointer to a QObject-derived object
|
// check to see if this is a pointer to a QObject-derived object
|
||||||
if (QMetaType::typeFlags(destTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) {
|
if (QMetaType::typeFlags(destTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) {
|
||||||
|
@ -458,10 +500,14 @@ bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& de
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// last chance, just convert it to a variant
|
// last chance, just convert it to a variant (impossible on V8)
|
||||||
// V8TODO
|
// V8TODO
|
||||||
qDebug() << "Converting: " << *v8::String::Utf8Value(_v8Isolate, val->ToDetailString(getConstContext()).ToLocalChecked())
|
QString errorMessage = QString() + "Converting: " + QString(*v8::String::Utf8Value(_v8Isolate, val->ToDetailString(getConstContext()).ToLocalChecked()))
|
||||||
<< "to variant. Destination type: " << QMetaType::typeName(destTypeId);
|
+ "to variant. Destination type: " + QMetaType::typeName(destTypeId);
|
||||||
|
qDebug() << errorMessage;
|
||||||
|
if(destTypeId == QMetaType::QVariant) {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
//dest = val->ToVariant();
|
//dest = val->ToVariant();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,6 +657,10 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
||||||
int bestMeta = 0;
|
int bestMeta = 0;
|
||||||
int bestConversionPenaltyScore = 0;
|
int bestConversionPenaltyScore = 0;
|
||||||
|
|
||||||
|
if(fullName() == "SettingsScriptingInterface::getValue") {
|
||||||
|
printf("SettingsScriptingInterface::getValue");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_metas; i++) {
|
for (int i = 0; i < num_metas; i++) {
|
||||||
const QMetaMethod& meta = _metas[i];
|
const QMetaMethod& meta = _metas[i];
|
||||||
int methodNumArgs = meta.parameterCount();
|
int methodNumArgs = meta.parameterCount();
|
||||||
|
@ -783,21 +787,25 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
||||||
int methodArgTypeId = meta.parameterType(arg);
|
int methodArgTypeId = meta.parameterType(arg);
|
||||||
Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
|
Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
|
||||||
v8::Local<v8::Value> argVal = arguments[arg];
|
v8::Local<v8::Value> argVal = arguments[arg];
|
||||||
if (methodArgTypeId != scriptValueTypeId && methodArgTypeId != QMetaType::QVariant) {
|
if (methodArgTypeId != scriptValueTypeId) {
|
||||||
QVariant varArgVal;
|
QVariant varArgVal;
|
||||||
if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) {
|
if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) {
|
||||||
QByteArray methodTypeName = QMetaType(methodArgTypeId).name();
|
QByteArray methodTypeName = QMetaType(methodArgTypeId).name();
|
||||||
QByteArray argTypeName = _engine->valueType(V8ScriptValue(isolate, argVal)).toLatin1();
|
QByteArray argTypeName = _engine->valueType(V8ScriptValue(isolate, argVal)).toLatin1();
|
||||||
isolate->ThrowError(v8::String::NewFromUtf8(isolate, QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4")
|
QString errorMessage = QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4")
|
||||||
.arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName).toStdString().c_str()).ToLocalChecked());
|
.arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName);
|
||||||
|
qDebug(scriptengine) << errorMessage;
|
||||||
|
isolate->ThrowError(v8::String::NewFromUtf8(isolate, errorMessage.toStdString().c_str()).ToLocalChecked());
|
||||||
//context->throwError(V8ScriptContext::TypeError, QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4")
|
//context->throwError(V8ScriptContext::TypeError, QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4")
|
||||||
// .arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName));
|
// .arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QString errorMessage = QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName());
|
||||||
isolate->ThrowError(v8::String::NewFromUtf8(isolate, QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName()).toStdString().c_str()).ToLocalChecked());
|
qDebug(scriptengine) << errorMessage;
|
||||||
|
isolate->ThrowError(v8::String::NewFromUtf8(isolate, errorMessage.toStdString().c_str()).ToLocalChecked());
|
||||||
|
// V8TODO: it happens sometimes for some reason
|
||||||
Q_ASSERT(false); // really shouldn't have gotten here -- it didn't work before and it's working now?
|
Q_ASSERT(false); // really shouldn't have gotten here -- it didn't work before and it's working now?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ bool ScriptProgramV8Wrapper::compile() {
|
||||||
auto isolate = _engine->getIsolate();
|
auto isolate = _engine->getIsolate();
|
||||||
v8::HandleScope handleScope(isolate);
|
v8::HandleScope handleScope(isolate);
|
||||||
auto context = _engine->getContext();
|
auto context = _engine->getContext();
|
||||||
|
v8::Context::Scope contextScope(context);
|
||||||
int errorColumnNumber = 0;
|
int errorColumnNumber = 0;
|
||||||
int errorLineNumber = 0;
|
int errorLineNumber = 0;
|
||||||
QString errorMessage = "";
|
QString errorMessage = "";
|
||||||
|
|
|
@ -183,7 +183,7 @@ ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValu
|
||||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qCritical() << "Failed to get property, parent of value: " << name << " is not a V8 object, reported type: " << QString(*v8::String::Utf8Value(isolate, _value.constGet()->TypeOf(isolate)));
|
qDebug() << "Failed to get property, parent of value: " << name << " is not a V8 object, reported type: " << QString(*v8::String::Utf8Value(isolate, _value.constGet()->TypeOf(isolate)));
|
||||||
return _engine->undefinedValue();
|
return _engine->undefinedValue();
|
||||||
/*v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
|
/*v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
|
||||||
V8ScriptValue nullScriptValue(_engine->getIsolate(), std::move(nullValue));
|
V8ScriptValue nullScriptValue(_engine->getIsolate(), std::move(nullValue));
|
||||||
|
|
|
@ -26,7 +26,9 @@ class QJsonValue;
|
||||||
|
|
||||||
inline bool isValidScale(glm::vec3 scale) {
|
inline bool isValidScale(glm::vec3 scale) {
|
||||||
bool result = scale.x != 0.0f && scale.y != 0.0f && scale.z != 0.0f;
|
bool result = scale.x != 0.0f && scale.y != 0.0f && scale.z != 0.0f;
|
||||||
assert(result);
|
// V8TODO: commented out for now
|
||||||
|
qWarning() << "Scale is equal to 0";
|
||||||
|
// assert(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue