mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 07:12:40 +02:00
Add V8 handle scopes
This commit is contained in:
parent
b4d21c38c3
commit
2b06c09318
10 changed files with 135 additions and 43 deletions
|
@ -33,7 +33,8 @@ ScriptContextV8Wrapper* ScriptContextV8Wrapper::unwrap(ScriptContext* val) {
|
|||
}
|
||||
|
||||
v8::Local<v8::Context> ScriptContextV8Wrapper::toV8Value() const {
|
||||
return _context.Get(_engine->getIsolate());
|
||||
v8::EscapableHandleScope handleScope(_engine->getIsolate());
|
||||
return handleScope.Escape(_context.Get(_engine->getIsolate()));
|
||||
}
|
||||
|
||||
int ScriptContextV8Wrapper::argumentCount() const {
|
||||
|
@ -42,6 +43,7 @@ int ScriptContextV8Wrapper::argumentCount() const {
|
|||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::argument(int index) const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
Q_ASSERT(_functionCallbackInfo);
|
||||
v8::Local<v8::Value> result = (*_functionCallbackInfo)[index];
|
||||
//V8ScriptValue result = _context->argument(index);
|
||||
|
@ -50,6 +52,7 @@ ScriptValue ScriptContextV8Wrapper::argument(int index) const {
|
|||
|
||||
QStringList ScriptContextV8Wrapper::backtrace() const {
|
||||
auto isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(isolate, 40);
|
||||
QStringList backTrace;
|
||||
//V8TODO nicer formatting
|
||||
|
@ -90,17 +93,20 @@ ScriptContextPointer ScriptContextV8Wrapper::parentContext() const {
|
|||
|
||||
ScriptValue ScriptContextV8Wrapper::thisObject() const {
|
||||
Q_ASSERT(_functionCallbackInfo);
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Value> result = _functionCallbackInfo->This();
|
||||
return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine->getIsolate(), result)));
|
||||
return ScriptValue();
|
||||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::throwError(const QString& text) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
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)));
|
||||
}
|
||||
|
||||
ScriptValue ScriptContextV8Wrapper::throwValue(const ScriptValue& value) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(value);
|
||||
if (!unwrapped) {
|
||||
return _engine->undefinedValue();
|
||||
|
|
|
@ -56,6 +56,7 @@ private: // storage
|
|||
|
||||
class ScriptFunctionContextV8Wrapper final : public ScriptFunctionContext {
|
||||
public: // construction
|
||||
//V8TODO
|
||||
inline ScriptFunctionContextV8Wrapper(v8::Local<v8::Context> context) { }
|
||||
|
||||
public: // ScriptFunctionContext implementation
|
||||
|
|
|
@ -293,6 +293,7 @@ ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8Scri
|
|||
return call;
|
||||
}
|
||||
QString Lambda::toString() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::String> string;
|
||||
QString qString("");
|
||||
if (_data.constGet()->ToString(_engine->getContext()).ToLocal(&string)) {
|
||||
|
@ -372,6 +373,7 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
|||
v8::Isolate::CreateParams isolateParams;
|
||||
isolateParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
_v8Isolate = v8::Isolate::New(isolateParams);
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(_v8Isolate);
|
||||
_v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context);
|
||||
|
||||
|
@ -434,7 +436,7 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value
|
|||
Q_ARG(V8ScriptValue, value));
|
||||
return;
|
||||
}*/
|
||||
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
QStringList pathToValue = valueName.split(".");
|
||||
int partsToGo = pathToValue.length();
|
||||
v8::Local<v8::Object> partObject = _v8Context.Get(_v8Isolate)->Global();
|
||||
|
@ -449,15 +451,21 @@ void ScriptEngineV8::registerValue(const QString& valueName, V8ScriptValue value
|
|||
//QObject *object = new QObject;
|
||||
v8::Local<v8::Object> partValue = v8::Object::New(_v8Isolate); //newQObject(object, QScriptEngine::ScriptOwnership);
|
||||
//V8ScriptValue partValue = QScriptEngine::newArray(); //newQObject(object, QScriptEngine::ScriptOwnership);
|
||||
Q_ASSERT(partObject->Set(_v8Context.Get(_v8Isolate), pathPartV8, partValue).FromMaybe(false));
|
||||
if (!partObject->Set(_v8Context.Get(_v8Isolate), pathPartV8, partValue).FromMaybe(false)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
} else {
|
||||
//partObject = currentPath->ToObject();
|
||||
//V8TODO: do these still happen if asserts are disabled?
|
||||
Q_ASSERT(partObject->Set(_v8Context.Get(_v8Isolate), pathPartV8, value.constGet()).FromMaybe(false));
|
||||
if (!partObject->Set(_v8Context.Get(_v8Isolate), pathPartV8, value.constGet()).FromMaybe(false)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
v8::Local<v8::Value> child;
|
||||
Q_ASSERT(partObject->Get(_v8Context.Get(_v8Isolate), pathPartV8).ToLocal(&child));
|
||||
if (!partObject->Get(_v8Context.Get(_v8Isolate), pathPartV8).ToLocal(&child)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,6 +483,7 @@ 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);
|
||||
v8::Local<v8::Object> v8GlobalObject = getContext()->Global();
|
||||
v8::Local<v8::String> v8Name = v8::String::NewFromUtf8(_v8Isolate, name.toStdString().c_str()).ToLocalChecked();
|
||||
|
||||
|
@ -575,6 +584,7 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure,
|
|||
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
|
||||
return nullValue();
|
||||
}
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
ScriptProgramV8Wrapper* unwrappedProgram = ScriptProgramV8Wrapper::unwrap(_program);
|
||||
if (unwrappedProgram == nullptr) {
|
||||
return nullValue();
|
||||
|
@ -699,6 +709,7 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
|||
}*/
|
||||
// Compile and check syntax
|
||||
// V8TODO: Could these all be replaced with checkSyntax function from wrapper?
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::TryCatch tryCatch(getIsolate());
|
||||
v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked());
|
||||
v8::Local<v8::Script> script;
|
||||
|
@ -776,7 +787,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
|||
Q_ARG(const ScriptProgramPointer&, program));
|
||||
return result;
|
||||
}*/
|
||||
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
||||
if (!unwrapped) {
|
||||
auto err = makeError(newValue("could not unwrap program"));
|
||||
|
@ -831,6 +842,7 @@ void ScriptEngineV8::updateMemoryCost(const qint64& deltaSize) {
|
|||
// ScriptEngine implementation
|
||||
|
||||
ScriptValue ScriptEngineV8::globalObject() const {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
V8ScriptValue global(_v8Isolate, getConstContext()->Global());// = QScriptEngine::globalObject(); // can't cache the value as it may change
|
||||
return ScriptValue(new ScriptValueV8Wrapper(const_cast<ScriptEngineV8*>(this), std::move(global)));
|
||||
}
|
||||
|
@ -845,6 +857,7 @@ ScriptValue ScriptEngineV8::newArray(uint length) {
|
|||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newArrayBuffer(const QByteArray& message) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
//V8TODO: this will leak memory
|
||||
std::shared_ptr<v8::BackingStore> backingStore(v8::ArrayBuffer::NewBackingStore(_v8Isolate, message.size()));
|
||||
std::memcpy(backingStore.get()->Data(), message.constData(), message.size());
|
||||
|
@ -900,23 +913,27 @@ ScriptValue ScriptEngineV8::newValue(uint value) {
|
|||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newValue(double value) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
V8ScriptValue result(_v8Isolate, v8::Number::New(_v8Isolate, value));
|
||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));
|
||||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newValue(const QString& value) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.toStdString().c_str(), v8::NewStringType::kNormal).ToLocalChecked();
|
||||
V8ScriptValue result(_v8Isolate, valueV8);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));
|
||||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newValue(const QLatin1String& value) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value.latin1(), v8::NewStringType::kNormal).ToLocalChecked();
|
||||
V8ScriptValue result(_v8Isolate, valueV8);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));
|
||||
}
|
||||
|
||||
ScriptValue ScriptEngineV8::newValue(const char* value) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::String> valueV8 = v8::String::NewFromUtf8(_v8Isolate, value, v8::NewStringType::kNormal).ToLocalChecked();
|
||||
V8ScriptValue result(_v8Isolate, valueV8);
|
||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));
|
||||
|
@ -986,6 +1003,7 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
|
|||
|
||||
auto v8FunctionCallback = [](const v8::FunctionCallbackInfo<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();
|
||||
auto function = reinterpret_cast<ScriptEngine::FunctionSignature>
|
||||
(info.Data()->ToObject(context).ToLocalChecked()->GetAlignedPointerFromInternalField(0));
|
||||
|
@ -1000,6 +1018,7 @@ ScriptValue ScriptEngineV8::newFunction(ScriptEngine::FunctionSignature fun, int
|
|||
//auto functionTemplate = v8::FunctionTemplate::New(_v8Isolate, v8FunctionCallback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), length);
|
||||
//auto functionData = v8::Object::New(_v8Isolate);
|
||||
//functionData->setIn
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
auto functionDataTemplate = v8::ObjectTemplate::New(_v8Isolate);
|
||||
functionDataTemplate->SetInternalFieldCount(3);
|
||||
auto functionData = functionDataTemplate->NewInstance(getContext()).ToLocalChecked();
|
||||
|
@ -1024,6 +1043,7 @@ void ScriptEngineV8::setObjectName(const QString& name) {
|
|||
|
||||
//V8TODO
|
||||
bool ScriptEngineV8::setProperty(const char* name, const QVariant& value) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Local<v8::Object> global = getContext()->Global();
|
||||
auto v8Name = v8::String::NewFromUtf8(getIsolate(), name).ToLocalChecked();
|
||||
V8ScriptValue v8Value = castVariantToValue(value);
|
||||
|
|
|
@ -175,7 +175,10 @@ public: // not for public use, but I don't like how Qt strings this along with p
|
|||
v8::EscapableHandleScope handleScope(_v8Isolate);
|
||||
return handleScope.Escape(_v8Context.Get(_v8Isolate));
|
||||
}
|
||||
const v8::Local<v8::Context> getConstContext() const {return _v8Context.Get(_v8Isolate);}
|
||||
const v8::Local<v8::Context> getConstContext() const {
|
||||
v8::EscapableHandleScope handleScope(_v8Isolate);
|
||||
return handleScope.Escape(_v8Context.Get(_v8Isolate));
|
||||
}
|
||||
|
||||
using ObjectWrapperMap = QMap<QObject*, QWeakPointer<ScriptObjectV8Proxy>>;
|
||||
mutable QMutex _qobjectWrapperMapProtect;
|
||||
|
|
|
@ -198,6 +198,7 @@ void ScriptEngineV8::registerSystemTypes() {
|
|||
}
|
||||
|
||||
int ScriptEngineV8::computeCastPenalty(const V8ScriptValue& v8Val, int destTypeId) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
const v8::Local<v8::Value> val = v8Val.constGet();
|
||||
if (val->IsNumber()) {
|
||||
switch (destTypeId){
|
||||
|
@ -291,6 +292,7 @@ int ScriptEngineV8::computeCastPenalty(const V8ScriptValue& v8Val, int destTypeI
|
|||
}
|
||||
|
||||
bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& dest, int destTypeId) {
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
const v8::Local<v8::Value> val = v8Val.constGet();
|
||||
|
||||
// if we're not particularly interested in a specific type, try to detect if we're dealing with a registered type
|
||||
|
@ -468,6 +470,8 @@ bool ScriptEngineV8::castValueToVariant(const V8ScriptValue& v8Val, QVariant& de
|
|||
}
|
||||
|
||||
QString ScriptEngineV8::valueType(const V8ScriptValue& v8Val) {
|
||||
// V8TODO
|
||||
v8::HandleScope handleScope(const_cast<v8::Isolate*>(v8Val.constGetIsolate()));
|
||||
const v8::Local<v8::Value> val = v8Val.constGet();
|
||||
|
||||
if (val->IsUndefined()) {
|
||||
|
|
|
@ -133,6 +133,8 @@ V8ScriptValue ScriptObjectV8Proxy::newQObject(ScriptEngineV8* engine, QObject* o
|
|||
}
|
||||
|
||||
ScriptObjectV8Proxy* ScriptObjectV8Proxy::unwrapProxy(const V8ScriptValue& val) {
|
||||
//V8TODO This shouldn't cause problems but I'm not sure if it's ok
|
||||
v8::HandleScope handleScope(const_cast<v8::Isolate*>(val.constGetIsolate()));
|
||||
auto v8Value = val.constGet();
|
||||
if (!v8Value->IsObject()) {
|
||||
return nullptr;
|
||||
|
@ -164,6 +166,8 @@ void ScriptObjectV8Proxy::investigate() {
|
|||
Q_ASSERT(qobject);
|
||||
if (!qobject) return;
|
||||
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
|
||||
auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());
|
||||
objectTemplate->SetInternalFieldCount(3);
|
||||
objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set));
|
||||
|
@ -464,6 +468,8 @@ V8ScriptValue ScriptVariantV8Proxy::newVariant(ScriptEngineV8* engine, const QVa
|
|||
}
|
||||
|
||||
ScriptVariantV8Proxy* ScriptVariantV8Proxy::unwrapProxy(const V8ScriptValue& val) {
|
||||
// V8TODO
|
||||
v8::HandleScope handleScope(const_cast<v8::Isolate*>(val.constGetIsolate()));
|
||||
auto v8Value = val.constGet();
|
||||
if (!v8Value->IsObject()) {
|
||||
return nullptr;
|
||||
|
@ -550,6 +556,8 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
|
|||
isolate->ThrowError("Referencing deleted native object");
|
||||
return;
|
||||
}
|
||||
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
|
||||
int scriptNumArgs = arguments.Length();
|
||||
int numArgs = std::min(scriptNumArgs, _numMaxParms);
|
||||
|
@ -898,6 +906,8 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu
|
|||
if (id != 0 || call != QMetaObject::InvokeMetaMethod) {
|
||||
return id;
|
||||
}
|
||||
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
|
||||
//V8ScriptValueList args(isolate, v8::Null(isolate));
|
||||
v8::Local<v8::Value> args[Q_METAMETHOD_INVOKE_MAX_ARGS];
|
||||
|
@ -952,12 +962,14 @@ ScriptSignalV8Proxy::ConnectionList::iterator ScriptSignalV8Proxy::findConnectio
|
|||
|
||||
void ScriptSignalV8Proxy::connect(V8ScriptValue arg0, V8ScriptValue arg1) {
|
||||
QObject* qobject = _object;
|
||||
v8::Isolate *isolate = _engine->getIsolate();
|
||||
if (!qobject) {
|
||||
_engine->getIsolate()->ThrowError("Referencing deleted native object");
|
||||
isolate->ThrowError("Referencing deleted native object");
|
||||
return;
|
||||
}
|
||||
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
||||
v8::Isolate *isolate = _engine->getIsolate();
|
||||
// untangle the arguments
|
||||
V8ScriptValue callback(isolate, v8::Null(isolate));
|
||||
V8ScriptValue callbackThis(isolate, v8::Null(isolate));
|
||||
|
@ -968,7 +980,7 @@ void ScriptSignalV8Proxy::connect(V8ScriptValue arg0, V8ScriptValue arg1) {
|
|||
callback = arg0;
|
||||
}
|
||||
if (!callback.get()->IsFunction()) {
|
||||
_engine->getIsolate()->ThrowError("Function expected as argument to 'connect'");
|
||||
isolate->ThrowError("Function expected as argument to 'connect'");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1030,11 +1042,12 @@ void ScriptSignalV8Proxy::connect(V8ScriptValue arg0, V8ScriptValue arg1) {
|
|||
|
||||
void ScriptSignalV8Proxy::disconnect(V8ScriptValue arg0, V8ScriptValue arg1) {
|
||||
QObject* qobject = _object;
|
||||
v8::Isolate *isolate = _engine->getIsolate();
|
||||
if (!qobject) {
|
||||
_engine->getIsolate()->ThrowError("Referencing deleted native object");
|
||||
isolate->ThrowError("Referencing deleted native object");
|
||||
return;
|
||||
}
|
||||
v8::Isolate *isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
||||
// untangle the arguments
|
||||
V8ScriptValue callback(isolate, v8::Null(isolate));
|
||||
|
@ -1046,7 +1059,7 @@ void ScriptSignalV8Proxy::disconnect(V8ScriptValue arg0, V8ScriptValue arg1) {
|
|||
callback = arg0;
|
||||
}
|
||||
if (!callback.get()->IsFunction()) {
|
||||
_engine->getIsolate()->ThrowError("Function expected as argument to 'disconnect'");
|
||||
isolate->ThrowError("Function expected as argument to 'disconnect'");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,29 +32,32 @@ ScriptSyntaxCheckResultPointer ScriptProgramV8Wrapper::checkSyntax() {
|
|||
}
|
||||
|
||||
bool ScriptProgramV8Wrapper::compile() {
|
||||
auto isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
auto context = _engine->getContext();
|
||||
int errorColumnNumber = 0;
|
||||
int errorLineNumber = 0;
|
||||
QString errorMessage = "";
|
||||
QString errorBacktrace = "";
|
||||
ScriptSyntaxCheckResult::State state;
|
||||
v8::TryCatch tryCatch(_engine->getIsolate());
|
||||
v8::ScriptOrigin scriptOrigin(_engine->getIsolate(), v8::String::NewFromUtf8(_engine->getIsolate(), _url.toStdString().c_str()).ToLocalChecked());
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
v8::ScriptOrigin scriptOrigin(isolate, v8::String::NewFromUtf8(isolate, _url.toStdString().c_str()).ToLocalChecked());
|
||||
v8::Local<v8::Script> script;
|
||||
if (v8::Script::Compile(_engine->getContext(), v8::String::NewFromUtf8(_engine->getIsolate(), _source.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
if (v8::Script::Compile(context, v8::String::NewFromUtf8(isolate, _source.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
_compileResult = ScriptSyntaxCheckResultV8Wrapper(ScriptSyntaxCheckResult::Valid);
|
||||
_value = V8ScriptProgram(_engine->getIsolate(), script);
|
||||
_value = V8ScriptProgram(isolate, script);
|
||||
return true;
|
||||
}
|
||||
v8::String::Utf8Value utf8Value(_engine->getIsolate(), tryCatch.Exception());
|
||||
v8::String::Utf8Value utf8Value(isolate, tryCatch.Exception());
|
||||
errorMessage = QString(*utf8Value);
|
||||
v8::Local<v8::Message> exceptionMessage = tryCatch.Message();
|
||||
if (!exceptionMessage.IsEmpty()) {
|
||||
errorLineNumber = exceptionMessage->GetLineNumber(_engine->getContext()).FromJust();
|
||||
errorColumnNumber = exceptionMessage->GetStartColumn(_engine->getContext()).FromJust();
|
||||
errorLineNumber = exceptionMessage->GetLineNumber(context).FromJust();
|
||||
errorColumnNumber = exceptionMessage->GetStartColumn(context).FromJust();
|
||||
v8::Local<v8::Value> backtraceV8String;
|
||||
if (tryCatch.StackTrace(_engine->getContext()).ToLocal(&backtraceV8String) && backtraceV8String->IsString() &&
|
||||
if (tryCatch.StackTrace(context).ToLocal(&backtraceV8String) && backtraceV8String->IsString() &&
|
||||
v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) {
|
||||
v8::String::Utf8Value backtraceUtf8Value(_engine->getIsolate(), backtraceV8String);
|
||||
v8::String::Utf8Value backtraceUtf8Value(isolate, backtraceV8String);
|
||||
errorBacktrace = *backtraceUtf8Value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,15 +14,17 @@
|
|||
#include "ScriptValueIteratorV8Wrapper.h"
|
||||
|
||||
V8ScriptValueIterator::V8ScriptValueIterator(ScriptEngineV8* engine, v8::Local<v8::Value> object) : _engine(engine) {
|
||||
_context.Reset(_engine->getIsolate(), _engine->getContext());
|
||||
auto context = _context.Get(_engine->getIsolate());
|
||||
auto isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
_context.Reset(isolate, _engine->getContext());
|
||||
auto context = _context.Get(isolate);
|
||||
v8::Local<v8::Object> v8Object;
|
||||
if (!object->ToObject(context).ToLocal(&v8Object)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
_object.Reset(_engine->getIsolate(), v8Object);
|
||||
_propertyNames.Reset(_engine->getIsolate(), v8Object->GetOwnPropertyNames(context).ToLocalChecked());
|
||||
_length = _propertyNames.Get(_engine->getIsolate())->Length();
|
||||
_object.Reset(isolate, v8Object);
|
||||
_propertyNames.Reset(isolate, v8Object->GetOwnPropertyNames(context).ToLocalChecked());
|
||||
_length = _propertyNames.Get(isolate)->Length();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
|
@ -31,12 +33,14 @@ bool V8ScriptValueIterator::hasNext() const {
|
|||
}
|
||||
|
||||
QString V8ScriptValueIterator::name() const {
|
||||
auto context = _context.Get(_engine->getIsolate());
|
||||
auto isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
auto context = _context.Get(isolate);
|
||||
v8::Local<v8::Value> propertyName;
|
||||
if (!_propertyNames.Get(_engine->getIsolate())->Get(context, _length).ToLocal(&propertyName)) {
|
||||
if (!_propertyNames.Get(isolate)->Get(context, _length).ToLocal(&propertyName)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return QString(*v8::String::Utf8Value(_engine->getIsolate(), propertyName));
|
||||
return QString(*v8::String::Utf8Value(isolate, propertyName));
|
||||
}
|
||||
|
||||
void V8ScriptValueIterator::next() {
|
||||
|
@ -46,16 +50,18 @@ void V8ScriptValueIterator::next() {
|
|||
}
|
||||
|
||||
V8ScriptValue V8ScriptValueIterator::value() {
|
||||
auto context = _context.Get(_engine->getIsolate());
|
||||
auto isolate = _engine->getIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
auto context = _context.Get(isolate);
|
||||
v8::Local<v8::Value> v8Value;
|
||||
v8::Local<v8::Value> propertyName;
|
||||
if (!_propertyNames.Get(_engine->getIsolate())->Get(context, _length).ToLocal(&propertyName)) {
|
||||
if (!_propertyNames.Get(isolate)->Get(context, _length).ToLocal(&propertyName)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
if (!_object.Get(_engine->getIsolate())->Get(context, propertyName->ToString(context).ToLocalChecked()).ToLocal(&v8Value)) {
|
||||
if (!_object.Get(isolate)->Get(context, propertyName->ToString(context).ToLocalChecked()).ToLocal(&v8Value)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return V8ScriptValue(_engine->getIsolate(), v8Value);
|
||||
return V8ScriptValue(isolate, v8Value);
|
||||
}
|
||||
|
||||
ScriptValue::PropertyFlags ScriptValueIteratorV8Wrapper::flags() const {
|
||||
|
|
|
@ -60,6 +60,7 @@ V8ScriptValue ScriptValueV8Wrapper::fullUnwrap(ScriptEngineV8* engine, const Scr
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const ScriptValueList& args) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
V8ScriptValue v8This = fullUnwrap(thisObject);
|
||||
//V8ScriptValueList qArgs;
|
||||
Q_ASSERT(args.length() <= Q_METAMETHOD_INVOKE_MAX_ARGS);
|
||||
|
@ -84,6 +85,7 @@ ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const Scri
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const ScriptValue& arguments) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
V8ScriptValue v8This = fullUnwrap(thisObject);
|
||||
V8ScriptValue v8Args = fullUnwrap(arguments);
|
||||
// V8TODO should there be a v8 try-catch here?
|
||||
|
@ -104,6 +106,7 @@ ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const Scri
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
Q_ASSERT(args.length() <= Q_METAMETHOD_INVOKE_MAX_ARGS);
|
||||
//V8TODO I'm not sure how else to do this since v8::Local should probably be on stack, not heap
|
||||
v8::Local<v8::Value> v8Args[Q_METAMETHOD_INVOKE_MAX_ARGS];
|
||||
|
@ -126,6 +129,7 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::construct(const ScriptValue& arguments) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
// V8TODO I'm not sure in what format arguments are yet, backtrace will show how it is used
|
||||
Q_ASSERT(false);
|
||||
return _engine->undefinedValue();
|
||||
|
@ -153,6 +157,7 @@ ScriptValueIteratorPointer ScriptValueV8Wrapper::newIterator() const {
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValue::ResolveFlags& mode) const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
if (!_value.constGet()->IsObject()) {
|
||||
//V8TODO: what about flags?
|
||||
v8::Local<v8::Value> resultLocal;
|
||||
|
@ -171,6 +176,7 @@ ScriptValue ScriptValueV8Wrapper::property(const QString& name, const ScriptValu
|
|||
}
|
||||
|
||||
ScriptValue ScriptValueV8Wrapper::property(quint32 arrayIndex, const ScriptValue::ResolveFlags& mode) const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
if (!_value.constGet()->IsObject()) {
|
||||
//V8TODO: what about flags?
|
||||
v8::Local<v8::Value> resultLocal;
|
||||
|
@ -191,6 +197,7 @@ void ScriptValueV8Wrapper::setData(const ScriptValue& value) {
|
|||
}
|
||||
|
||||
void ScriptValueV8Wrapper::setProperty(const QString& name, const ScriptValue& value, const ScriptValue::PropertyFlags& flags) {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
V8ScriptValue unwrapped = fullUnwrap(value);
|
||||
if(_value.constGet()->IsObject()) {
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(_engine->getIsolate(), name.toStdString().c_str(),v8::NewStringType::kNormal).ToLocalChecked();
|
||||
|
@ -237,47 +244,65 @@ void ScriptValueV8Wrapper::setPrototype(const ScriptValue& prototype) {
|
|||
}
|
||||
|
||||
bool ScriptValueV8Wrapper::strictlyEquals(const ScriptValue& other) const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
ScriptValueV8Wrapper* unwrappedOther = unwrap(other);
|
||||
return unwrappedOther ? _value.constGet()->StrictEquals(unwrappedOther->toV8Value().constGet()) : false;
|
||||
}
|
||||
|
||||
bool ScriptValueV8Wrapper::toBool() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
return _value.constGet()->ToBoolean(_engine->getIsolate())->Value();
|
||||
}
|
||||
|
||||
qint32 ScriptValueV8Wrapper::toInt32() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Integer> *integer;
|
||||
Q_ASSERT(_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer));
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return static_cast<int32_t>((*integer)->Value());
|
||||
}
|
||||
|
||||
double ScriptValueV8Wrapper::toInteger() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Integer> *integer;
|
||||
Q_ASSERT(_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer));
|
||||
if (!_value.constGet()->ToInteger(_value.constGetContext()).ToLocal(integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*integer)->Value();
|
||||
}
|
||||
|
||||
double ScriptValueV8Wrapper::toNumber() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Number> *number;
|
||||
Q_ASSERT(_value.constGet()->ToNumber(_value.constGetContext()).ToLocal(number));
|
||||
if (!_value.constGet()->ToNumber(_value.constGetContext()).ToLocal(number)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*number)->Value();
|
||||
}
|
||||
|
||||
QString ScriptValueV8Wrapper::toString() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::String::Utf8Value string(_engine->getIsolate(), _value.constGet());
|
||||
Q_ASSERT(*string != nullptr);
|
||||
return QString(*string);
|
||||
}
|
||||
|
||||
quint16 ScriptValueV8Wrapper::toUInt16() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Uint32> *integer;
|
||||
Q_ASSERT(_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer));
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return static_cast<uint16_t>((*integer)->Value());
|
||||
}
|
||||
|
||||
quint32 ScriptValueV8Wrapper::toUInt32() const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
v8::Local<v8::Uint32> *integer;
|
||||
Q_ASSERT(_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer));
|
||||
if (!_value.constGet()->ToUint32(_value.constGetContext()).ToLocal(integer)) {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return (*integer)->Value();
|
||||
}
|
||||
|
||||
|
@ -302,6 +327,7 @@ QObject* ScriptValueV8Wrapper::toQObject() const {
|
|||
}
|
||||
|
||||
bool ScriptValueV8Wrapper::equals(const ScriptValue& other) const {
|
||||
v8::HandleScope handleScope(_engine->getIsolate());
|
||||
ScriptValueV8Wrapper* unwrappedOther = unwrap(other);
|
||||
//V8TODO: does this work with different contexts/isolates?
|
||||
// in such case conversion will probably be necessary
|
||||
|
|
|
@ -24,13 +24,23 @@ public:
|
|||
//V8ScriptValueTemplate(v8::Isolate *isolate, v8::Local<T> value) : _isolate(isolate) {
|
||||
//_value.reset(v8::UniquePersistent<T>::New(_isolate, value));
|
||||
//};
|
||||
V8ScriptValueTemplate(v8::Isolate *isolate, const v8::Local<T> value) : _isolate(isolate), _context(isolate, isolate->GetCurrentContext()) {
|
||||
V8ScriptValueTemplate(v8::Isolate *isolate, const v8::Local<T> value) : _isolate(isolate) {
|
||||
//_value.reset(_isolate, value);
|
||||
v8::HandleScope handleScope(_isolate);
|
||||
_context.Reset(isolate, isolate->GetCurrentContext());
|
||||
_value.reset(new v8::UniquePersistent<T>(_isolate, std::move(value)));
|
||||
};
|
||||
v8::Local<T> get() {return _value.get()->Get(_isolate);};
|
||||
const v8::Local<T> constGet() const {return _value.get()->Get(_isolate);};
|
||||
V8ScriptValueTemplate<T>&& copy() const {return new V8ScriptValueTemplate(_isolate, v8::Local<T>::New(_isolate, constGet()));};
|
||||
v8::Local<T> get() {
|
||||
v8::EscapableHandleScope handleScope(_isolate);
|
||||
return _value.get()->Get(_isolate);
|
||||
};
|
||||
const v8::Local<T> constGet() const {
|
||||
v8::EscapableHandleScope handleScope(_isolate);
|
||||
return _value.get()->Get(_isolate);
|
||||
};
|
||||
V8ScriptValueTemplate<T>&& copy() const {
|
||||
v8::HandleScope handleScope(_isolate);
|
||||
return new V8ScriptValueTemplate(_isolate, v8::Local<T>::New(_isolate, constGet()));};
|
||||
const v8::Local<v8::Context> constGetContext() const {
|
||||
v8::EscapableHandleScope handleScope(_isolate);
|
||||
return handleScope.Escape(_context.Get(_isolate));
|
||||
|
|
Loading…
Reference in a new issue