Added makeError and script value prototype getter

This commit is contained in:
ksuprynowicz 2023-05-07 19:08:04 +02:00
parent 13e22d4931
commit 833bffc285
6 changed files with 73 additions and 30 deletions

View file

@ -44,7 +44,9 @@ using ScriptProgramPointer = std::shared_ptr<ScriptProgram>;
Q_DECLARE_METATYPE(ScriptEnginePointer);
template <typename T>
inline ScriptValue scriptValueFromValue(ScriptEngine* engine, const T& t);
inline ScriptValue
scriptValueFromValue(ScriptEngine* engine, const T& t);
template <typename T>
inline T scriptvalue_cast(const ScriptValue& value);

View file

@ -45,6 +45,7 @@ public:
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual ScriptValue prototype() const override;
virtual void setData(const ScriptValue& val) override;
virtual bool hasProperty(const QString &name) const override;
virtual void setProperty(const QString& name,
@ -55,7 +56,7 @@ public:
const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override;
virtual void setPrototype(const ScriptValue& prototype) override;
virtual bool strictlyEquals(const ScriptValue& other) const override;
virtual inline QList<QString> getPropertyNames() const override;
virtual QList<QString> getPropertyNames() const override;
virtual bool toBool() const override;
virtual qint32 toInt32() const override;
@ -177,6 +178,10 @@ ScriptValue ScriptValueProxyNull::property(quint32 arrayIndex, const ScriptValue
return ScriptValue();
}
ScriptValue ScriptValueProxyNull::prototype() const {
return ScriptValue();
}
void ScriptValueProxyNull::setData(const ScriptValue& val) {
Q_ASSERT(false);
qCWarning(scriptengine_script, "ScriptValue::setData called on empty value");

View file

@ -90,6 +90,7 @@ public:
inline ScriptValueIteratorPointer newIterator() const;
inline ScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
inline ScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const;
inline ScriptValue prototype() const;
inline void setData(const ScriptValue& val);
inline bool hasProperty(const QString &name) const;
inline void setProperty(const QString& name,
@ -154,6 +155,7 @@ public:
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const = 0;
virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const = 0;
virtual ScriptValue prototype() const = 0;
virtual void setData(const ScriptValue& val) = 0;
virtual bool hasProperty(const QString &name) const = 0;
virtual void setProperty(const QString& name,
@ -318,6 +320,11 @@ ScriptValue ScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode)
return _proxy->property(arrayIndex, mode);
}
ScriptValue ScriptValue::prototype() const {
Q_ASSERT(_proxy != nullptr);
return _proxy->prototype();
}
void ScriptValue::setData(const ScriptValue& val) {
Q_ASSERT(_proxy != nullptr);
return _proxy->setData(val);

View file

@ -46,6 +46,7 @@
#include "../ScriptEngineLogging.h"
#include "../ScriptProgram.h"
#include "../ScriptEngineCast.h"
#include "../ScriptValue.h"
#include "ScriptContextV8Wrapper.h"
@ -53,6 +54,7 @@
#include "ScriptProgramV8Wrapper.h"
#include "ScriptValueV8Wrapper.h"
#include "ScriptEngineLoggingV8.h"
#include "ScriptValueIteratorV8Wrapper.h"
static const int MAX_DEBUG_VALUE_LENGTH { 80 };
@ -77,46 +79,40 @@ ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString&
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
return nullValue();
}
v8::Locker locker(_v8Isolate);
v8::Isolate::Scope isolateScope(_v8Isolate);
v8::HandleScope handleScope(_v8Isolate);
v8::Context::Scope contextScope(getContext());
return nullValue();
}
//V8TODO: do not remove until ScriptEngineV8::makeError is implemented
/*
auto other = _other;
if (_other.constGet()->IsString()) {
other = QScriptEngine::newObject();
if (_other.isString()) {
other = newObject();
other.setProperty("message", _other.toString());
}
auto proto = QScriptEngine::globalObject().property(type);
auto proto = globalObject().property(type);
if (!proto.isFunction()) {
proto = QScriptEngine::globalObject().property(other.prototype().property("constructor").property("name").toString());
proto = globalObject().property(other.prototype().property("constructor").property("name").toString());
}
if (!proto.isFunction()) {
#ifdef DEBUG_JS_EXCEPTIONS
qCDebug(shared) << "BaseScriptEngine::makeError -- couldn't find constructor for" << type << " -- using Error instead";
#endif
proto = QScriptEngine::globalObject().property("Error");
proto = globalObject().property("Error");
}
if (other.engine() != this) {
if (other.engine().get() != this) {
// JS Objects are parented to a specific script engine instance
// -- this effectively ~clones it locally by routing through a QVariant and back
other = QScriptEngine::toScriptValue(other.toVariant());
other = toScriptValue(other.toVariant());
}
// ~ var err = new Error(other.message)
auto err = proto.construct(V8ScriptValueList({ other.property("message") }));
auto err = proto.construct(ScriptValueList({ other.property("message") }));
// transfer over any existing properties
V8ScriptValueIterator it(other);
while (it.hasNext()) {
it.next();
err.setProperty(it.name(), it.value());
auto it = other.newIterator();
while (it->hasNext()) {
it->next();
err.setProperty(it->name(), it->value());
}
return err;*/
//}
return err;
}
// check syntax and when there are issues returns an actual "SyntaxError" with the details

View file

@ -153,7 +153,8 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
}
v8::Local<v8::Function> v8Function = v8::Local<v8::Function>::Cast(_value.get());
//V8TODO: I'm not sure if this is correct, maybe use CallAsContructor instead?
// V8TODO: I'm not sure if this is correct, maybe use CallAsConstructor instead?
// Maybe it's CallAsConstructor for function and NewInstance for class?
auto maybeResult = v8Function->NewInstance(_engine->getContext(), args.length(), v8Args);
v8::Local<v8::Object> result;
if (maybeResult.ToLocal(&result)) {
@ -319,6 +320,24 @@ ScriptValue ScriptValueV8Wrapper::property(quint32 arrayIndex, const ScriptValue
return _engine->undefinedValue();
}
ScriptValue ScriptValueV8Wrapper::prototype() const {
auto isolate = _engine->getIsolate();
v8::Locker locker(isolate);
v8::Isolate::Scope isolateScope(isolate);
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(_engine->getContext());
auto value = _value.constGet();
if (!value->IsObject()) {
return _engine->undefinedValue();
}
auto object = v8::Local<v8::Object>::Cast(value);
auto prototype = object->GetPrototype();
V8ScriptValue result(_engine, prototype);
return ScriptValue(new ScriptValueV8Wrapper(_engine, result));
}
void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
auto isolate = _engine->getIsolate();
v8::Locker locker(isolate);
@ -612,13 +631,26 @@ bool ScriptValueV8Wrapper::isBool() const {
}
bool ScriptValueV8Wrapper::isError() const {
//auto isolate = _engine->getIsolate();
// Q_ASSERT(isolate->IsCurrent());
// v8::HandleScope handleScope(isolate);
// v8::Context::Scope contextScope(_engine->getContext());
//V8TODO
auto isolate = _engine->getIsolate();
v8::Locker locker(isolate);
v8::Isolate::Scope isolateScope(isolate);
v8::HandleScope handleScope(isolate);
auto context = _engine->getContext();
v8::Context::Scope contextScope(_engine->getContext());
v8::Local<v8::Value> error;
if (!context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "Error").ToLocalChecked()).ToLocal(&error)) {
Q_ASSERT(false);
}
if (!error->IsObject()) {
Q_ASSERT(false);
}
auto errorObj = v8::Local<v8::Object>::Cast(error);
if (_value.constGet()->InstanceOf(context, errorObj).FromMaybe(false)) {
qDebug() << "ScriptValueV8Wrapper::isError : true";
return true;
}
qDebug() << "ScriptValueV8Wrapper::isError : false";
return false;
//return _value.constGet()->IsError();
}
bool ScriptValueV8Wrapper::isFunction() const {

View file

@ -57,6 +57,7 @@ public: // ScriptValue implementation
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual ScriptValue property(quint32 arrayIndex,
const ScriptValue::ResolveFlags& mode = ScriptValue::ResolvePrototype) const override;
virtual ScriptValue prototype() const override;
virtual void setData(const ScriptValue& val) override;
virtual bool hasProperty(const QString &name) const override;