More fixes for V8

This commit is contained in:
ksuprynowicz 2022-12-05 00:22:15 +01:00
parent 2f9f78fb87
commit 97137c7b13
9 changed files with 212 additions and 70 deletions

View file

@ -147,11 +147,18 @@ ScriptValue ScriptContextV8Wrapper::thisObject() const {
ScriptValue ScriptContextV8Wrapper::throwError(const QString& text) {
auto isolate = _engine->getIsolate();
Q_ASSERT(isolate->IsCurrent());
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(_engine->getContext());
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)));
// V8TODO: I have no idea how to do this yet because it happens on another thread
if(isolate->IsCurrent()) {
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(_engine->getContext());
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)));
} else {
qWarning() << "throwError on a different thread not implemented yet, error value: " << text;
return _engine->undefinedValue();
}
}
ScriptValue ScriptContextV8Wrapper::throwValue(const ScriptValue& value) {

View file

@ -370,7 +370,7 @@ v8::Platform* ScriptEngineV8::getV8Platform() {
}
ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
_scriptManager(scriptManager)
_scriptManager(scriptManager), _isEvaluating(false)
//V8TODO
//_arrayBufferClass(new ArrayBufferClass(this))
{
@ -514,21 +514,34 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object)
#ifdef THREAD_DEBUGGING
qCDebug(scriptengine) << "ScriptEngineV8::registerGlobalObject() called on thread [" << QThread::currentThread() << "] name:" << name;
#endif
v8::HandleScope handleScope(_v8Isolate);
Q_ASSERT(_v8Isolate->IsCurrent());
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
v8::Local<v8::Object> v8GlobalObject = getContext()->Global();
v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
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);
Q_ASSERT(_v8Isolate->IsCurrent());
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
v8::Local<v8::Object> v8GlobalObject = getContext()->Global();
v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
// V8TODO: Is IsEmpty check enough or IsValid is needed too?
if (!v8GlobalObject->Get(getContext(), v8Name).IsEmpty()) {
if (object) {
V8ScriptValue value = ScriptObjectV8Proxy::newQObject(this, object, ScriptEngine::QtOwnership);
v8GlobalObject->Set(getContext(), v8Name, value.get());
} else {
v8GlobalObject->Set(getContext(), v8Name, v8::Null(_v8Isolate));
// V8TODO: Is IsEmpty check enough or IsValid is needed too?
if (!v8GlobalObject->Get(getContext(), v8Name).IsEmpty()) {
if (object) {
V8ScriptValue value = ScriptObjectV8Proxy::newQObject(this, object, ScriptEngine::QtOwnership);
v8GlobalObject->Set(getContext(), v8Name, value.get());
} else {
v8GlobalObject->Set(getContext(), v8Name, v8::Null(_v8Isolate));
}
}
}
if (is_isolate_exit_needed) {
_v8Isolate->Exit();
_v8Locker.reset(nullptr);
}
}
void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
@ -548,13 +561,26 @@ void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::Functio
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] name:" << name;
#endif
//auto scriptFun = static_cast<ScriptValueV8Wrapper*>(newFunction(functionSignature, numArguments).ptr())->toV8Value().constGet();
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
auto scriptFun = newFunction(functionSignature, numArguments);
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();
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
auto scriptFun = newFunction(functionSignature, numArguments);
//getContext()->Global().Set();
globalObject().setProperty(name, scriptFun);
//getContext()->Global().Set();
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) {
@ -572,12 +598,25 @@ void ScriptEngineV8::registerFunction(const QString& parent, const QString& name
qCDebug(scriptengine) << "ScriptEngineV8::registerFunction() called on thread [" << QThread::currentThread() << "] parent:" << parent << "name:" << name;
#endif
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
ScriptValue object = globalObject().property(parent);
if (object.isValid()) {
ScriptValue scriptFun = newFunction(functionSignature, numArguments);
object.setProperty(name, scriptFun);
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::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
ScriptValue object = globalObject().property(parent);
if (object.isValid()) {
ScriptValue scriptFun = newFunction(functionSignature, numArguments);
object.setProperty(name, scriptFun);
}
}
if (is_isolate_exit_needed) {
_v8Isolate->Exit();
_v8Locker.reset(nullptr);
}
}
@ -599,10 +638,18 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
qCDebug(scriptengine) << "ScriptEngineV8::registerGetterSetter() called on thread [" << QThread::currentThread() << "] name:" << name << "parent:" << parent;
#endif
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(getContext());
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::Context::Scope contextScope(getContext());
/*auto getterFunction = [](v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
/*auto getterFunction = [](v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
//V8TODO: is using GetCurrentContext ok, or context wrapper needs to be added?
v8::HandleScope handleScope(info.GetIsolate());
auto context = info.GetIsolate()->GetCurrentContext();
@ -636,35 +683,44 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
};*/
ScriptValue setterFunction = newFunction(setter, 1);
ScriptValue getterFunction = newFunction(getter);
V8ScriptValue unwrappedGetter = ScriptValueV8Wrapper::fullUnwrap(this, setterFunction);
V8ScriptValue unwrappedSetter = ScriptValueV8Wrapper::fullUnwrap(this, getterFunction);
v8::PropertyDescriptor propertyDescriptor(unwrappedGetter.get(), unwrappedSetter.get());
ScriptValue setterFunction = newFunction(setter, 1);
ScriptValue getterFunction = newFunction(getter);
V8ScriptValue unwrappedGetter = ScriptValueV8Wrapper::fullUnwrap(this, setterFunction);
V8ScriptValue unwrappedSetter = ScriptValueV8Wrapper::fullUnwrap(this, getterFunction);
v8::PropertyDescriptor propertyDescriptor(unwrappedGetter.get(), unwrappedSetter.get());
//V8TODO: Getters/setters are probably done in a different way in V8. Maybe object template is needed?
if (!parent.isNull() && !parent.isEmpty()) {
ScriptValue object = globalObject().property(parent);
if (object.isValid()) {
V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object);
Q_ASSERT(v8parent.get()->IsObject());
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();
if(!v8object->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \"" << parent << "\"";
//V8TODO: Getters/setters are probably done in a different way in V8. Maybe object template is needed?
if (!parent.isNull() && !parent.isEmpty()) {
ScriptValue object = globalObject().property(parent);
if (object.isValid()) {
V8ScriptValue v8parent = ScriptValueV8Wrapper::fullUnwrap(this, object);
Q_ASSERT(v8parent.get()->IsObject());
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();
if (!v8object->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for parent: \""
<< parent << "\"";
}
//object.setProperty(name, setterFunction, ScriptValue::PropertySetter);
//object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);
} else {
qCDebug(scriptengine) << "Parent object \"" << parent << "\" for registerGetterSetter \"" << name
<< "\" is not valid: ";
}
//object.setProperty(name, setterFunction, ScriptValue::PropertySetter);
//object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);
} else {
qCDebug(scriptengine) << "Parent object \"" << parent << "\" for registerGetterSetter \"" << name << "\" is not valid: ";
v8::Local<v8::String> v8propertyName =
v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
if (!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object";
}
//globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);
//globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
}
} else {
v8::Local<v8::String> v8propertyName = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
if(!getContext()->Global()->DefineProperty(getContext(), v8propertyName, propertyDescriptor).FromMaybe(false)) {
qCDebug(scriptengine) << "DefineProperty failed for registerGetterSetter \"" << name << "\" for global object";
}
//globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);
//globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
}
if (is_isolate_exit_needed) {
_v8Isolate->Exit();
_v8Locker.reset(nullptr);
}
}
@ -674,10 +730,13 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
return nullValue();
}
Q_ASSERT(!isEvaluating());
_isEvaluating = true;
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
if (unwrappedProgram == nullptr) {
_isEvaluating = false;
return nullValue();
}
const V8ScriptProgram& program = unwrappedProgram->toV8Value();
@ -687,10 +746,12 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
ScriptValueV8Wrapper* unwrappedClosure = ScriptValueV8Wrapper::unwrap(_closure);
if (unwrappedClosure == nullptr) {
_isEvaluating = false;
return nullValue();
}
const V8ScriptValue& closure = unwrappedClosure->toV8Value();
if (!closure.constGet()->IsObject()) {
_isEvaluating = false;
return nullValue();
}
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> closureGlobal;
if (!closureObject->Get(closure.constGetContext() ,v8::String::NewFromUtf8(_v8Isolate, "global").ToLocalChecked()).ToLocal(&closureGlobal)) {
_isEvaluating = false;
return nullValue();
}
@ -721,6 +783,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
v8::Local<v8::Value> thiz;
// 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)) {
_isEvaluating = false;
return nullValue();
}
//thiz = closure.property("this");
@ -776,6 +839,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
}*/
//_v8Context.Get(_v8Isolate)->Enter();
_isEvaluating = false;
return result;
}
@ -801,6 +865,8 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
// Compile and check syntax
// V8TODO: Could these all be replaced with checkSyntax function from wrapper?
Q_ASSERT(!_v8Isolate->IsDead());
Q_ASSERT(!isEvaluating());
_isEvaluating = true;
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
v8::TryCatch tryCatch(getIsolate());
@ -830,6 +896,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
auto err = makeError(newValue(errorMessage));
raiseException(err);
maybeEmitUncaughtException("compile");
_isEvaluating = false;
return err;
}
qCDebug(scriptengine) << "Script compilation succesful: " << fileName;
@ -863,9 +930,11 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
//V8TODO
//raiseException(errorValue);
//maybeEmitUncaughtException("evaluate");
_isEvaluating = false;
return errorValue;
}
V8ScriptValue resultValue(_v8Isolate, result);
_isEvaluating = false;
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));
return result;
}
Q_ASSERT(!isEvaluating());
_isEvaluating = true;
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
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"));
raiseException(err);
maybeEmitUncaughtException("compile");
_isEvaluating = false;
return err;
}
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
@ -924,6 +996,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
auto err = makeError(newValue(syntaxCheck->errorMessage()));
raiseException(err);
maybeEmitUncaughtException("compile");
_isEvaluating = false;
return err;
}
@ -945,9 +1018,11 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
raiseException(errorValue);
maybeEmitUncaughtException("evaluate");
_isEvaluating = false;
return errorValue;
}
V8ScriptValue resultValue(_v8Isolate, result);
_isEvaluating = false;
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: should it be compiled on creation?
//V8ScriptProgram result(sourceCode, fileName);
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
}
@ -1132,8 +1209,8 @@ bool ScriptEngineV8::hasUncaughtException() const {
}
bool ScriptEngineV8::isEvaluating() const {
//V8TODO
//return QScriptEngine::isEvaluating();
return _isEvaluating;
return false;
}

View file

@ -228,6 +228,7 @@ protected:
//V8TODO
//ArrayBufferClass* _arrayBufferClass;
bool _isEvaluating;
};
// Lambda helps create callable V8ScriptValues out of std::functions:

View file

@ -433,6 +433,48 @@ bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& de
case QMetaType::QObjectStar:
dest = QVariant::fromValue(ScriptObjectV8Proxy::unwrap(v8Val));
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:
// check to see if this is a pointer to a QObject-derived object
if (QMetaType::typeFlags(destTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) {
@ -458,10 +500,14 @@ bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& de
break;
}
}
// last chance, just convert it to a variant
// last chance, just convert it to a variant (impossible on V8)
// V8TODO
qDebug() << "Converting: " << *v8::String::Utf8Value(_v8Isolate, val->ToDetailString(getConstContext()).ToLocalChecked())
<< "to variant. Destination type: " << QMetaType::typeName(destTypeId);
QString errorMessage = QString() + "Converting: " + QString(*v8::String::Utf8Value(_v8Isolate, val->ToDetailString(getConstContext()).ToLocalChecked()))
+ "to variant. Destination type: " + QMetaType::typeName(destTypeId);
qDebug() << errorMessage;
if(destTypeId == QMetaType::QVariant) {
Q_ASSERT(false);
}
//dest = val->ToVariant();
break;
}

View file

@ -657,6 +657,10 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
int bestMeta = 0;
int bestConversionPenaltyScore = 0;
if(fullName() == "SettingsScriptingInterface::getValue") {
printf("SettingsScriptingInterface::getValue");
}
for (int i = 0; i < num_metas; i++) {
const QMetaMethod& meta = _metas[i];
int methodNumArgs = meta.parameterCount();
@ -783,21 +787,25 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
int methodArgTypeId = meta.parameterType(arg);
Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
v8::Local<v8::Value> argVal = arguments[arg];
if (methodArgTypeId != scriptValueTypeId && methodArgTypeId != QMetaType::QVariant) {
if (methodArgTypeId != scriptValueTypeId) {
QVariant varArgVal;
if (!_engine->castValueToVariant(V8ScriptValue(isolate, argVal), varArgVal, methodArgTypeId)) {
QByteArray methodTypeName = QMetaType(methodArgTypeId).name();
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")
.arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName).toStdString().c_str()).ToLocalChecked());
QString errorMessage = QString("Native call of %1 failed: Cannot convert parameter %2 from %3 to %4")
.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")
// .arg(fullName()).arg(arg+1).arg(argTypeName, methodTypeName));
return;
}
}
}
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());
QString errorMessage = QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName());
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?
return;
}

View file

@ -35,6 +35,7 @@ bool ScriptProgramV8Wrapper::compile() {
auto isolate = _engine->getIsolate();
v8::HandleScope handleScope(isolate);
auto context = _engine->getContext();
v8::Context::Scope contextScope(context);
int errorColumnNumber = 0;
int errorLineNumber = 0;
QString errorMessage = "";

View file

@ -50,7 +50,7 @@ public: // construction
_engine(engine), _value(value) {}*/
//inline ScriptProgramV8Wrapper(ScriptEngineV8* engine, V8ScriptProgram&& value) :
// _engine(engine), _value(std::move(value)) {}
inline ScriptProgramV8Wrapper(ScriptEngineV8* engine, QString source, QString url) :
inline ScriptProgramV8Wrapper(ScriptEngineV8* engine, QString source, QString url) :
_engine(engine), _source(source), _url(url), _value(engine->getIsolate(), v8::Local<v8::Script>()) {}
static ScriptProgramV8Wrapper* unwrap(ScriptProgramPointer val);
bool compile();

View file

@ -183,7 +183,7 @@ ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValu
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();
/*v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
V8ScriptValue nullScriptValue(_engine->getIsolate(), std::move(nullValue));

View file

@ -26,7 +26,9 @@ class QJsonValue;
inline bool isValidScale(glm::vec3 scale) {
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;
}