mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 07:12:40 +02:00
Script engine new function fixes
This commit is contained in:
parent
a4c6930a50
commit
58a221541f
6 changed files with 199 additions and 98 deletions
|
@ -683,14 +683,15 @@ void ScriptManager::init() {
|
|||
|
||||
scriptEngine->registerGlobalObject("Script", this);
|
||||
|
||||
{
|
||||
//V8TODO: V8 has no such global object?
|
||||
/*{
|
||||
// set up Script.require.resolve and Script.require.cache
|
||||
auto Script = scriptEngine->globalObject().property("Script");
|
||||
auto require = Script.property("require");
|
||||
auto resolve = Script.property("_requireResolve");
|
||||
require.setProperty("resolve", resolve, READONLY_PROP_FLAGS);
|
||||
resetModuleCache();
|
||||
}
|
||||
}*/
|
||||
|
||||
scriptEngine->registerEnum("Script.ExternalPaths", QMetaEnum::fromType<ExternalResource::Bucket>());
|
||||
|
||||
|
|
|
@ -16,12 +16,17 @@
|
|||
#include "ScriptEngineV8.h"
|
||||
#include "ScriptValueV8Wrapper.h"
|
||||
|
||||
ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::Local<v8::Context> context) : _engine(engine) {
|
||||
_context.Reset(_engine->getIsolate(), _engine->getConstContext());
|
||||
/*ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::Local<v8::Context> context) : _functionCallbackInfo(nullptr), _propertyCallbackInfo(nullptr), _engine(engine) {
|
||||
_context.Reset(_engine->getIsolate(), context);
|
||||
}*/
|
||||
|
||||
ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine) : _functionCallbackInfo(nullptr), _propertyCallbackInfo(nullptr), _engine(engine) {
|
||||
}
|
||||
|
||||
ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::Local<v8::Context> context, std::shared_ptr<v8::FunctionCallbackInfo<v8::Value>> functionCallbackInfo) : _context(engine->getIsolate(), engine->getConstContext()), _functionCallbackInfo(functionCallbackInfo), _engine(engine) {
|
||||
_context.Reset(_engine->getIsolate(), _engine->getConstContext());
|
||||
ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::FunctionCallbackInfo<v8::Value> *functionCallbackInfo) : _functionCallbackInfo(functionCallbackInfo), _propertyCallbackInfo(nullptr), _engine(engine) {
|
||||
}
|
||||
|
||||
ScriptContextV8Wrapper::ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::PropertyCallbackInfo<v8::Value> *propertyCallbackInfo) : _functionCallbackInfo(nullptr), _propertyCallbackInfo(propertyCallbackInfo), _engine(engine) {
|
||||
}
|
||||
|
||||
ScriptContextV8Wrapper* ScriptContextV8Wrapper::unwrap(ScriptContext* val) {
|
||||
|
@ -34,7 +39,7 @@ ScriptContextV8Wrapper* ScriptContextV8Wrapper::unwrap(ScriptContext* val) {
|
|||
|
||||
v8::Local<v8::Context> ScriptContextV8Wrapper::toV8Value() const {
|
||||
v8::EscapableHandleScope handleScope(_engine->getIsolate());
|
||||
return handleScope.Escape(_context.Get(_engine->getIsolate()));
|
||||
return handleScope.Escape(_engine->getContext());
|
||||
}
|
||||
|
||||
int ScriptContextV8Wrapper::argumentCount() const {
|
||||
|
@ -44,21 +49,35 @@ int ScriptContextV8Wrapper::argumentCount() const {
|
|||
v8::Context::Scope contextScope(_engine->getContext());*/
|
||||
//Q_ASSERT(_functionCallbackInfo);A
|
||||
// V8TODO
|
||||
return Q_METAMETHOD_INVOKE_MAX_ARGS;
|
||||
if (_functionCallbackInfo) {
|
||||
return _functionCallbackInfo->kArgsLength;
|
||||
} else if (_propertyCallbackInfo) {
|
||||
return _propertyCallbackInfo->kArgsLength;
|
||||
} else {
|
||||
return Q_METAMETHOD_INVOKE_MAX_ARGS;
|
||||
}
|
||||
// This was wrong, in function registration it seems to be used as maximum number od arguments instead?
|
||||
// Is it also used for something else?
|
||||
//return _functionCallbackInfo->Length();
|
||||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::argument(int index) const {
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
Q_ASSERT(_functionCallbackInfo);
|
||||
v8::Local<v8::Value> result = (*_functionCallbackInfo)[index];
|
||||
//V8ScriptValue result = _context->argument(index);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
if (_functionCallbackInfo) {
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Value> result = (*_functionCallbackInfo)[index];
|
||||
if (index < _functionCallbackInfo->kArgsLength) {
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
} else {
|
||||
return _engine->undefinedValue();
|
||||
}
|
||||
} else if (_propertyCallbackInfo) {
|
||||
return _engine->undefinedValue();
|
||||
} else {
|
||||
return _engine->undefinedValue();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ScriptContextV8Wrapper::backtrace() const {
|
||||
|
@ -82,11 +101,12 @@ QStringList ScriptContextV8Wrapper::backtrace() const {
|
|||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::callee() const {
|
||||
Q_ASSERT(false);
|
||||
//V8TODO
|
||||
//Can this be done with CurrentStackTrace?
|
||||
//V8ScriptValue result = _context->callee();
|
||||
//return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||
return ScriptValue();
|
||||
return _engine->undefinedValue();
|
||||
}
|
||||
|
||||
ScriptEnginePointer ScriptContextV8Wrapper::engine() const {
|
||||
|
@ -94,25 +114,35 @@ ScriptEnginePointer ScriptContextV8Wrapper::engine() const {
|
|||
}
|
||||
|
||||
ScriptFunctionContextPointer ScriptContextV8Wrapper::functionContext() const {
|
||||
return std::make_shared<ScriptFunctionContextV8Wrapper>(_context.Get(_engine->getIsolate()));
|
||||
return std::make_shared<ScriptFunctionContextV8Wrapper>(_engine->getContext());
|
||||
}
|
||||
|
||||
ScriptContextPointer ScriptContextV8Wrapper::parentContext() const {
|
||||
//V8TODO
|
||||
Q_ASSERT(false);
|
||||
//V8ScriptContext* result = _context->parentContext();
|
||||
//return result ? std::make_shared<ScriptContextV8Wrapper>(_engine, result) : ScriptContextPointer();
|
||||
return ScriptContextPointer();
|
||||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::thisObject() const {
|
||||
Q_ASSERT(_functionCallbackInfo);
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Value> result = _functionCallbackInfo->This();
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
return ScriptValue();
|
||||
if (_functionCallbackInfo) {
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Value> result = _functionCallbackInfo->This();
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
} else if (_propertyCallbackInfo) {
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Value> result = _propertyCallbackInfo->This();
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
} else {
|
||||
return _engine->undefinedValue();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::throwError(const QString& text) {
|
||||
|
|
|
@ -31,8 +31,9 @@ class ScriptEngineV8;
|
|||
/// [V8] Implements ScriptContext for V8 and translates calls for V8ScriptContextInfo
|
||||
class ScriptContextV8Wrapper final : public ScriptContext {
|
||||
public: // construction
|
||||
ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::Local<v8::Context> context);
|
||||
ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::Local<v8::Context> context, std::shared_ptr<v8::FunctionCallbackInfo<v8::Value>> functionCallbackInfo);
|
||||
ScriptContextV8Wrapper(ScriptEngineV8* engine);
|
||||
ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::FunctionCallbackInfo<v8::Value> *functionCallbackInfo);
|
||||
ScriptContextV8Wrapper(ScriptEngineV8* engine, const v8::PropertyCallbackInfo<v8::Value> *propertyCallbackInfo);
|
||||
static ScriptContextV8Wrapper* unwrap(ScriptContext* val);
|
||||
v8::Local<v8::Context> toV8Value() const;
|
||||
|
||||
|
@ -49,8 +50,8 @@ public: // ScriptContext implementation
|
|||
virtual ScriptValue throwValue(const ScriptValue& value) override;
|
||||
|
||||
private: // storage
|
||||
v8::Persistent<v8::Context> _context;
|
||||
std::shared_ptr<v8::FunctionCallbackInfo<v8::Value>> _functionCallbackInfo;
|
||||
const v8::FunctionCallbackInfo<v8::Value> *_functionCallbackInfo;
|
||||
const v8::PropertyCallbackInfo<v8::Value> *_propertyCallbackInfo;
|
||||
ScriptEngineV8* _engine;
|
||||
};
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8Scri
|
|||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
auto lambda = new Lambda(this, operation, data);
|
||||
auto object = newQObject(lambda, ownership);
|
||||
//V8TODO?
|
||||
//V8TODO - I'm not sure if this works
|
||||
auto call = object.property("call");
|
||||
call.setPrototype(object); // context->callee().prototype() === Lambda QObject
|
||||
call.setData(ScriptValue(new ScriptValueV8Wrapper(this, data))); // context->callee().data() will === data param
|
||||
|
@ -334,8 +334,10 @@ V8ScriptValue Lambda::call() {
|
|||
if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
|
||||
return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
|
||||
}
|
||||
return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
|
||||
// V8TODO: something is obviously wrong here, there's no call at all?
|
||||
// V8TODO: it needs to be done in entirely different way for V8
|
||||
Q_ASSERT(false);
|
||||
//return _operation(_engine->getContext(), _engine);
|
||||
//return V8ScriptValue(_engine->getIsolate(), v8::Null(_engine->getIsolate()));
|
||||
//return operation(static_cast<QScriptEngine*>(engine)->currentContext(), engine);
|
||||
}
|
||||
|
||||
|
@ -379,30 +381,35 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
|||
v8::V8::Initialize();
|
||||
} );
|
||||
_v8InitMutex.unlock();
|
||||
v8::Isolate::CreateParams isolateParams;
|
||||
isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
_v8Isolate = v8::Isolate::New(isolateParams);
|
||||
_v8Isolate->Enter();
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);
|
||||
Q_ASSERT(!context.IsEmpty());
|
||||
_v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context);
|
||||
{
|
||||
v8::Isolate::CreateParams isolateParams;
|
||||
isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
_v8Isolate = v8::Isolate::New(isolateParams);
|
||||
_v8Isolate->Enter();
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);
|
||||
Q_ASSERT(!context.IsEmpty());
|
||||
v8::Context::Scope contextScope(context);
|
||||
_v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context);
|
||||
|
||||
registerSystemTypes();
|
||||
V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate));
|
||||
_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
|
||||
|
||||
// V8TODO: dispose of isolate on ScriptEngineV8 destruction
|
||||
//v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate));
|
||||
//_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null)));
|
||||
V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate));
|
||||
_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
|
||||
V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate));
|
||||
_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined));
|
||||
|
||||
//V8ScriptValue undefined = v8::UniquePersistent<v8::Value>(_v8Isolate,v8::Undefined(_v8Isolate));
|
||||
//_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(undefined)));
|
||||
V8ScriptValue undefined(_v8Isolate, v8::Undefined(_v8Isolate));
|
||||
_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, undefined));
|
||||
registerSystemTypes();
|
||||
|
||||
// V8TODO:
|
||||
//QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND);
|
||||
// V8TODO: dispose of isolate on ScriptEngineV8 destruction
|
||||
//v8::UniquePersistent<v8::Value> null = v8::UniquePersistent<v8::Value>(_v8Isolate, v8::Null(_v8Isolate));
|
||||
//_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(null)));
|
||||
|
||||
//V8ScriptValue undefined = v8::UniquePersistent<v8::Value>(_v8Isolate,v8::Undefined(_v8Isolate));
|
||||
//_undefinedValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(undefined)));
|
||||
|
||||
// V8TODO:
|
||||
//QScriptEngine::setProcessEventsInterval(MSECS_PER_SECOND);
|
||||
}
|
||||
|
||||
//_currentThread = QThread::currentThread();
|
||||
|
||||
|
@ -514,6 +521,8 @@ void ScriptEngineV8::registerGlobalObject(const QString& name, QObject* object)
|
|||
}
|
||||
|
||||
void ScriptEngineV8::registerFunction(const QString& name, ScriptEngine::FunctionSignature functionSignature, int numArguments) {
|
||||
//if (QThread::currentThread() != ) {
|
||||
//}
|
||||
if (QThread::currentThread() != thread()) {
|
||||
#ifdef THREAD_DEBUGGING
|
||||
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
|
|||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
ScriptValue object = globalObject().property(parent);
|
||||
if (object.isValid()) {
|
||||
ScriptValue scriptFun = ScriptEngine::newFunction(functionSignature, numArguments);
|
||||
ScriptValue scriptFun = newFunction(functionSignature, numArguments);
|
||||
object.setProperty(name, scriptFun);
|
||||
}
|
||||
}
|
||||
|
@ -580,20 +589,71 @@ void ScriptEngineV8::registerGetterSetter(const QString& name, ScriptEngine::Fun
|
|||
#endif
|
||||
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
v8::Context::Scope contextScope(getContext());
|
||||
|
||||
/*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();
|
||||
v8::Context::Scope contextScope(context);
|
||||
auto object = v8::Local<v8::Object>::Cast(info.Data());
|
||||
Q_ASSERT(object->InternalFieldCount() == 2);
|
||||
auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
|
||||
(object->GetAlignedPointerFromInternalField(0));
|
||||
ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
|
||||
(object->GetAlignedPointerFromInternalField(1));
|
||||
ScriptContextV8Wrapper scriptContext(scriptEngine, &info);
|
||||
//V8TODO: this scriptContext needs to have FunctionCallbackInfo added
|
||||
ScriptValue result = function(&scriptContext, scriptEngine);
|
||||
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
|
||||
info.GetReturnValue().Set(unwrapped->toV8Value().constGet());
|
||||
};
|
||||
auto setterFunction = [](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();
|
||||
v8::Context::Scope contextScope(context);
|
||||
auto object = v8::Local<v8::Object>::Cast(info.Data());
|
||||
Q_ASSERT(object->InternalFieldCount() == 2);
|
||||
auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
|
||||
(object->GetAlignedPointerFromInternalField(0));
|
||||
ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
|
||||
(object->GetAlignedPointerFromInternalField(1));
|
||||
ScriptContextV8Wrapper scriptContext(scriptEngine, &info);
|
||||
//V8TODO: this scriptContext needs to have FunctionCallbackInfo added
|
||||
ScriptValue result = function(&scriptContext, scriptEngine);
|
||||
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());
|
||||
|
||||
//V8TODO: Getters/setters are probably done in a different way in V8. Maybe object template is needed?
|
||||
if (!parent.isNull() && !parent.isEmpty()) {
|
||||
ScriptValue object = ScriptEngine::globalObject().property(parent);
|
||||
ScriptValue object = globalObject().property(parent);
|
||||
if (object.isValid()) {
|
||||
object.setProperty(name, setterFunction, ScriptValue::PropertySetter);
|
||||
object.setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
||||
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: ";
|
||||
}
|
||||
} else {
|
||||
globalObject().setProperty(name, setterFunction, ScriptValue::PropertySetter);
|
||||
globalObject().setProperty(name, getterFunction, ScriptValue::PropertyGetter);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -783,8 +843,9 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
|||
Q_ASSERT(tryCatchRun.HasCaught());
|
||||
auto runError = tryCatchRun.Message();
|
||||
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
||||
raiseException(errorValue);
|
||||
maybeEmitUncaughtException("evaluate");
|
||||
//V8TODO
|
||||
//raiseException(errorValue);
|
||||
//maybeEmitUncaughtException("evaluate");
|
||||
return errorValue;
|
||||
}
|
||||
V8ScriptValue resultValue(_v8Isolate, result);
|
||||
|
@ -1016,8 +1077,8 @@ ScriptContext* ScriptEngineV8::currentContext() const {
|
|||
}*/
|
||||
//_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), localCtx);
|
||||
if (!_currContext) {
|
||||
// I'm not sure how to do this without discardin const
|
||||
_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this), getConstContext());
|
||||
// I'm not sure how to do this without discarding const
|
||||
_currContext = std::make_shared<ScriptContextV8Wrapper>(const_cast<ScriptEngineV8*>(this));
|
||||
}
|
||||
return _currContext.get();
|
||||
}
|
||||
|
@ -1025,11 +1086,13 @@ ScriptContext* ScriptEngineV8::currentContext() const {
|
|||
bool ScriptEngineV8::hasUncaughtException() const {
|
||||
//V8TODO
|
||||
//return QScriptEngine::hasUncaughtException();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScriptEngineV8::isEvaluating() const {
|
||||
//V8TODO
|
||||
//return QScriptEngine::isEvaluating();
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int length) {
|
||||
|
@ -1050,13 +1113,14 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
|
|||
auto context = info.GetIsolate()->GetCurrentContext();
|
||||
v8::Context::Scope contextScope(context);
|
||||
auto object = v8::Local<v8::Object>::Cast(info.Data());
|
||||
Q_ASSERT(object->InternalFieldCount() == 2);
|
||||
auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
|
||||
(object->GetAlignedPointerFromInternalField(0));
|
||||
ScriptContext *scriptContext = reinterpret_cast<ScriptContext*>
|
||||
(object->GetAlignedPointerFromInternalField(1));;
|
||||
ScriptEngineV8 *scriptEngine = reinterpret_cast<ScriptEngineV8*>
|
||||
(object->GetAlignedPointerFromInternalField(2));;
|
||||
ScriptValue result = function(scriptContext, scriptEngine);
|
||||
(object->GetAlignedPointerFromInternalField(1));
|
||||
ScriptContextV8Wrapper scriptContext(scriptEngine, &info);
|
||||
//V8TODO: this scriptContext needs to have FunctionCallbackInfo added
|
||||
ScriptValue result = function(&scriptContext, scriptEngine);
|
||||
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(result);
|
||||
info.GetReturnValue().Set(unwrapped->toV8Value().constGet());
|
||||
};
|
||||
|
@ -1066,11 +1130,10 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
|
|||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);
|
||||
functionDataTemplate->SetInternalFieldCount(3);
|
||||
functionDataTemplate->SetInternalFieldCount(2);
|
||||
auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();
|
||||
functionData->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(fun));
|
||||
functionData->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(this));
|
||||
functionData->SetAlignedPointerInInternalField(2, reinterpret_cast<void*>(currentContext()));
|
||||
//functionData->SetInternalField(3, v8::Null(_v8Isolate));
|
||||
auto v8Function = v8::Function::New(getContext(), v8FunctionCallback, functionData, length).ToLocalChecked();
|
||||
//auto functionObjectTemplate = functionTemplate->InstanceTemplate();
|
||||
|
@ -1138,10 +1201,12 @@ int ScriptEngineV8::uncaughtExceptionLineNumber() const {
|
|||
|
||||
bool ScriptEngineV8::raiseException(const ScriptValue& exception) {
|
||||
//V8TODO
|
||||
Q_ASSERT(false);
|
||||
//Q_ASSERT(false);
|
||||
qCritical() << "Script exception occured: " << exception.toString();
|
||||
/*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(exception);
|
||||
V8ScriptValue qException = unwrapped ? unwrapped->toV8Value() : QScriptEngine::newVariant(exception.toVariant());
|
||||
return raiseException(qException);*/
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::create(int type, const void* ptr) {
|
||||
|
@ -1171,4 +1236,5 @@ QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) {
|
|||
}
|
||||
|
||||
return var;
|
||||
return QVariant();
|
||||
}
|
||||
|
|
|
@ -237,9 +237,9 @@ void ScriptObjectV8Proxy::investigate() {
|
|||
SignalDef& signalDef = _signals.insert(idx, SignalDef(_engine->getIsolate(), name.get())).value();
|
||||
signalDef.name = name;
|
||||
signalDef.signal = method;
|
||||
qDebug(scriptengine) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString));
|
||||
qDebug(scriptengine) << "Utf8Value 2: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), name.constGet()));
|
||||
qDebug(scriptengine) << "toQString: " << name.toQString();
|
||||
//qDebug(scriptengine) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString));
|
||||
//qDebug(scriptengine) << "Utf8Value 2: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), name.constGet()));
|
||||
//qDebug(scriptengine) << "toQString: " << name.toQString();
|
||||
methodNames.insert(name, idx);
|
||||
} else {
|
||||
int originalMethodId = nameLookup.value();
|
||||
|
|
|
@ -168,25 +168,26 @@ ScriptValueIteratorPointer ScriptValueV8Wrapper::newIterator() const {
|
|||
return std::make_shared<ScriptValueIteratorV8Wrapper>(_engine, _value);
|
||||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValue::ResolveFlags& mode) const {
|
||||
ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValue::ResolveFlags &mode) const {
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
if (!_value.constGet()->IsObject()) {
|
||||
if (_value.constGet()->IsObject()) {
|
||||
//V8TODO: what about flags?
|
||||
v8::Local<v8::Value> resultLocal;
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(_engine->getIsolate(), name.toStdString().c_str(),v8::NewStringType::kNormal).ToLocalChecked();
|
||||
Q_ASSERT(_value.constGet()->IsObject());
|
||||
const v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(_value.constGet());
|
||||
if (object->Get(_value.constGetContext(), key).ToLocal(&resultLocal)) {
|
||||
V8ScriptValue result(_engine->getIsolate(), resultLocal);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||
}
|
||||
}
|
||||
v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
|
||||
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)));
|
||||
return _engine->undefinedValue();
|
||||
/*v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
|
||||
V8ScriptValue nullScriptValue(_engine->getIsolate(), std::move(nullValue));
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, nullScriptValue));
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, nullScriptValue));*/
|
||||
//V8ScriptValue result = _value.property(name, (V8ScriptValue::ResolveFlags)(int)mode);
|
||||
//return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||
}
|
||||
|
@ -196,19 +197,20 @@ ScriptValue ScriptValueV8Wrapper::property(quint32 arrayIndex, const ScriptValue
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
if (!_value.constGet()->IsObject()) {
|
||||
if (_value.constGet()->IsObject()) {
|
||||
//V8TODO: what about flags?
|
||||
v8::Local<v8::Value> resultLocal;
|
||||
Q_ASSERT(_value.constGet()->IsObject());
|
||||
const v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(_value.constGet());
|
||||
if (object->Get(_value.constGetContext(), arrayIndex).ToLocal(&resultLocal)) {
|
||||
V8ScriptValue result(_engine->getIsolate(), resultLocal);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, std::move(result)));
|
||||
}
|
||||
}
|
||||
v8::Local<v8::Value> nullValue = v8::Null(_engine->getIsolate());
|
||||
qCritical() << "Failed to get property, parent of value: " << arrayIndex << " 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));
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, nullScriptValue));
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, nullScriptValue));*/
|
||||
}
|
||||
|
||||
void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
|
||||
|
@ -221,6 +223,7 @@ void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
|
|||
}
|
||||
|
||||
void ScriptValueV8Wrapper::setProperty(const QString& name, const ScriptValue& value, const ScriptValue::PropertyFlags& flags) {
|
||||
Q_ASSERT(flags != ScriptValue::PropertyGetter || flags != ScriptValue::PropertySetter);
|
||||
auto isolate = _engine->getIsolate();
|
||||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
@ -304,11 +307,11 @@ qint32 ScriptValueV8Wrapper::toInt32() const {
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Integer> *integer;
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer)) {
|
||||
v8::Local<v8::Integer> integer;
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(&integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return static_cast<int32_t>((*integer)->Value());
|
||||
return static_cast<int32_t>((integer)->Value());
|
||||
}
|
||||
|
||||
double ScriptValueV8Wrapper::toInteger() const {
|
||||
|
@ -316,11 +319,11 @@ double ScriptValueV8Wrapper::toInteger() const {
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Integer> *integer;
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer)) {
|
||||
v8::Local<v8::Integer> integer;
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(&integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*integer)->Value();
|
||||
return (integer)->Value();
|
||||
}
|
||||
|
||||
double ScriptValueV8Wrapper::toNumber() const {
|
||||
|
@ -328,11 +331,11 @@ double ScriptValueV8Wrapper::toNumber() const {
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Number> *number;
|
||||
if (!_value.constGet()->ToNumber(_value.constGetContext()).ToLocal(number)) {
|
||||
v8::Local<v8::Number> number;
|
||||
if (!_value.constGet()->ToNumber(_value.constGetContext()).ToLocal(&number)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*number)->Value();
|
||||
return number->Value();
|
||||
}
|
||||
|
||||
QString ScriptValueV8Wrapper::toString() const {
|
||||
|
@ -350,11 +353,11 @@ quint16 ScriptValueV8Wrapper::toUInt16() const {
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Uint32> *integer;
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer)) {
|
||||
v8::Local<v8::Uint32> integer;
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(&integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return static_cast<uint16_t>((*integer)->Value());
|
||||
return static_cast<uint16_t>(integer->Value());
|
||||
}
|
||||
|
||||
quint32 ScriptValueV8Wrapper::toUInt32() const {
|
||||
|
@ -362,11 +365,11 @@ quint32 ScriptValueV8Wrapper::toUInt32() const {
|
|||
Q_ASSERT(isolate->IsCurrent());
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Context::Scope contextScope(_engine->getContext());
|
||||
v8::Local<v8::Uint32> *integer;
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer)) {
|
||||
v8::Local<v8::Uint32> integer;
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(&integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*integer)->Value();
|
||||
return integer->Value();
|
||||
}
|
||||
|
||||
QVariant ScriptValueV8Wrapper::toVariant() const {
|
||||
|
|
Loading…
Reference in a new issue