mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Added simple compile test function
This commit is contained in:
parent
38064b95c5
commit
827ddf5958
7 changed files with 83 additions and 19 deletions
|
@ -85,7 +85,7 @@ public:
|
|||
virtual bool hasUncaughtException() const = 0;
|
||||
virtual bool isEvaluating() const = 0;
|
||||
//virtual ScriptValue lintScript(const QString& sourceCode, const QString& fileName, const int lineNumber = 1) = 0;
|
||||
virtual ScriptValue cheskScriptSyntax(ScriptProgramPointer program) = 0;
|
||||
virtual ScriptValue checkScriptSyntax(ScriptProgramPointer program) = 0;
|
||||
virtual ScriptValue makeError(const ScriptValue& other = ScriptValue(), const QString& type = "Error") = 0;
|
||||
virtual ScriptManager* manager() const = 0;
|
||||
virtual bool maybeEmitUncaughtException(const QString& debugHint = QString()) = 0;
|
||||
|
@ -126,6 +126,7 @@ public:
|
|||
virtual int uncaughtExceptionLineNumber() const = 0;
|
||||
virtual void updateMemoryCost(const qint64& deltaSize) = 0;
|
||||
virtual void requestCollectGarbage() = 0;
|
||||
virtual void compileTest() = 0;
|
||||
|
||||
public:
|
||||
// helper to detect and log warnings when other code invokes QScriptEngine/BaseScriptEngine in thread-unsafe ways
|
||||
|
|
|
@ -826,6 +826,8 @@ void ScriptManager::run() {
|
|||
// (because we're a client script)
|
||||
hifi::scripting::setLocalAccessSafeThread(true);
|
||||
}
|
||||
|
||||
_engine->compileTest();
|
||||
|
||||
_engine->enterIsolateOnThisThread();
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString&
|
|||
}
|
||||
|
||||
// check syntax and when there are issues returns an actual "SyntaxError" with the details
|
||||
ScriptValue ScriptEngineV8::cheskScriptSyntax(ScriptProgramPointer program) {
|
||||
ScriptValue ScriptEngineV8::checkScriptSyntax(ScriptProgramPointer program) {
|
||||
if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) {
|
||||
return nullValue();
|
||||
}
|
||||
|
@ -375,10 +375,13 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
|||
//_arrayBufferClass(new ArrayBufferClass(this))
|
||||
{
|
||||
_v8InitMutex.lock();
|
||||
std::call_once ( _v8InitOnceFlag, [ ]{
|
||||
std::call_once ( _v8InitOnceFlag, [ ]{
|
||||
v8::V8::InitializeExternalStartupData("");
|
||||
//V8TODO might cause crashes if it's too much
|
||||
v8::V8::SetFlagsFromString("--stack-size=900000");
|
||||
v8::Platform* platform = getV8Platform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
v8::V8::Initialize(); qCDebug(scriptengine) << "V8 platform initialized";
|
||||
} );
|
||||
_v8InitMutex.unlock();
|
||||
{
|
||||
|
@ -391,7 +394,8 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
|||
Q_ASSERT(!context.IsEmpty());
|
||||
v8::Context::Scope contextScope(context);
|
||||
_v8Context = v8::UniquePersistent<v8::Context>(_v8Isolate, context);
|
||||
|
||||
|
||||
|
||||
V8ScriptValue nullScriptValue(_v8Isolate, v8::Null(_v8Isolate));
|
||||
_nullValue = ScriptValue(new ScriptValueV8Wrapper(this, nullScriptValue));
|
||||
|
||||
|
@ -427,7 +431,7 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
|
|||
}
|
||||
}, Qt::DirectConnection);*/
|
||||
//moveToThread(scriptManager->thread());
|
||||
setThread(scriptManager->thread());
|
||||
//setThread(scriptManager->thread());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -789,6 +793,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?
|
||||
Q_ASSERT(!_v8Isolate->IsDead());
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
v8::TryCatch tryCatch(getIsolate());
|
||||
|
@ -799,7 +804,8 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
|||
int errorLineNumber = 0;
|
||||
QString errorMessage = "";
|
||||
QString errorBacktrace = "";
|
||||
v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception());
|
||||
//v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception());
|
||||
v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Message()->Get());
|
||||
errorMessage = QString(*utf8Value);
|
||||
v8::Local<v8::Message> exceptionMessage = tryCatch.Message();
|
||||
if (!exceptionMessage.IsEmpty()) {
|
||||
|
@ -811,12 +817,14 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
|
|||
v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String);
|
||||
errorBacktrace = *backtraceUtf8Value;
|
||||
}
|
||||
qCDebug(scriptengine) << "Compiling script \"" << fileName << "\" failed on line " << errorLineNumber << " column " << errorColumnNumber << " with message: \"" << errorMessage <<"\" backtrace: " << errorBacktrace;
|
||||
}
|
||||
auto err = makeError(newValue(errorMessage));
|
||||
raiseException(err);
|
||||
maybeEmitUncaughtException("compile");
|
||||
return err;
|
||||
}
|
||||
qCDebug(scriptengine) << "Script compilation succesful: " << fileName;
|
||||
|
||||
//V8TODO
|
||||
/*auto syntaxError = lintScript(sourceCode, fileName);
|
||||
|
@ -1170,16 +1178,20 @@ QThread* ScriptEngineV8::thread() const {
|
|||
}
|
||||
|
||||
void ScriptEngineV8::setThread(QThread* thread) {
|
||||
qDebug() << "Moved script engine " << objectName() << " to different thread";
|
||||
_v8Isolate->Exit();
|
||||
if (_v8Isolate->IsCurrent()) {
|
||||
_v8Isolate->Exit();
|
||||
qDebug() << "Script engine " << objectName() << " exited isolate";
|
||||
}
|
||||
moveToThread(thread);
|
||||
QMetaObject::invokeMethod(this, "enterIsolateOnThisThread");
|
||||
qDebug() << "Moved script engine " << objectName() << " to different thread";
|
||||
}
|
||||
|
||||
void ScriptEngineV8::enterIsolateOnThisThread() {
|
||||
Q_ASSERT(thread() == QThread::currentThread());
|
||||
_v8Isolate->Enter();
|
||||
qDebug() << "Script engine " << objectName() << " entered isolate on a new thread";
|
||||
if (!_v8Isolate->IsCurrent()) {
|
||||
_v8Isolate->Enter();
|
||||
qDebug() << "Script engine " << objectName() << " entered isolate on a new thread";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1238,3 +1250,18 @@ QVariant ScriptEngineV8::convert(const ScriptValue& value, int typeId) {
|
|||
return var;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ScriptEngineV8::compileTest() {
|
||||
v8::Locker locker(_v8Isolate);
|
||||
v8::Isolate::Scope isolateScope(_v8Isolate);
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
v8::Local<v8::Script> script;
|
||||
v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(),"test").ToLocalChecked());
|
||||
if (v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), "print(\"hello world\");").ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
qCDebug(scriptengine) << "Compile test succesful";
|
||||
} else {
|
||||
qCDebug(scriptengine) << "Compile test failed";
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public: // ScriptEngine implementation
|
|||
virtual bool hasUncaughtException() const override;
|
||||
virtual bool isEvaluating() const override;
|
||||
//virtual ScriptValue lintScript(const QString& sourceCode, const QString& fileName, const int lineNumber = 1) override;
|
||||
virtual ScriptValue cheskScriptSyntax(ScriptProgramPointer program) override;
|
||||
virtual ScriptValue checkScriptSyntax(ScriptProgramPointer program) override;
|
||||
virtual ScriptValue makeError(const ScriptValue& other, const QString& type = "Error") override;
|
||||
virtual ScriptManager* manager() const override;
|
||||
|
||||
|
@ -126,6 +126,7 @@ public: // ScriptEngine implementation
|
|||
virtual int uncaughtExceptionLineNumber() const override;
|
||||
virtual void updateMemoryCost(const qint64& deltaSize) override;
|
||||
virtual void requestCollectGarbage() override { while(!_v8Isolate->IdleNotificationDeadline(getV8Platform()->MonotonicallyIncreasingTime() + GARBAGE_COLLECTION_TIME_LIMIT_S)) {}; }
|
||||
virtual void compileTest() override;
|
||||
|
||||
// helper to detect and log warnings when other code invokes QScriptEngine/BaseScriptEngine in thread-unsafe ways
|
||||
inline bool IS_THREADSAFE_INVOCATION(const QString& method) { return ScriptEngine::IS_THREADSAFE_INVOCATION(method); }
|
||||
|
|
|
@ -44,10 +44,12 @@ bool ScriptProgramV8Wrapper::compile() {
|
|||
v8::ScriptOrigin scriptOrigin(isolate, v8::String::NewFromUtf8(isolate, _url.toStdString().c_str()).ToLocalChecked());
|
||||
v8::Local<v8::Script> script;
|
||||
if (v8::Script::Compile(context, v8::String::NewFromUtf8(isolate, _source.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
|
||||
qDebug() << "Script compilation succesful: " << _url;
|
||||
_compileResult = ScriptSyntaxCheckResultV8Wrapper(ScriptSyntaxCheckResult::Valid);
|
||||
_value = V8ScriptProgram(isolate, script);
|
||||
return true;
|
||||
}
|
||||
qDebug() << "Script compilation failed: " << _url;
|
||||
v8::String::Utf8Value utf8Value(isolate, tryCatch.Exception());
|
||||
errorMessage = QString(*utf8Value);
|
||||
v8::Local<v8::Message> exceptionMessage = tryCatch.Message();
|
||||
|
|
|
@ -76,15 +76,20 @@ void ScriptEngineTests::scriptTest() {
|
|||
QVERIFY(!ac.isNull());
|
||||
|
||||
|
||||
ac->loadOneScript("test-missing.js");
|
||||
ac->loadOneScript("test-hello.js");
|
||||
ac->loadOneScript("test-divide-by-zero.js");
|
||||
ac->loadOneScript("test1.js");
|
||||
//ac->loadOneScript("test-missing.js");
|
||||
//ac->loadOneScript("test-hello.js");
|
||||
//ac->loadOneScript("test-divide-by-zero.js");
|
||||
qDebug() << ac->getRunning();
|
||||
|
||||
|
||||
QSignalSpy spy(ac.get(), SIGNAL(scriptCountChanged));
|
||||
spy.wait(5000);
|
||||
ac->shutdownScripting();
|
||||
while (true) {
|
||||
QSignalSpy spy(ac.get(), SIGNAL(scriptCountChanged));
|
||||
spy.wait(3000000);
|
||||
qDebug() << "Signal happened";
|
||||
}
|
||||
//spy.wait(5000);
|
||||
//ac->shutdownScripting();
|
||||
|
||||
|
||||
}
|
||||
|
|
26
tests/script-engine/src/ScriptEngineTests.h
Normal file
26
tests/script-engine/src/ScriptEngineTests.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// AudioTests.h
|
||||
// tests/audio/src
|
||||
//
|
||||
// Created by Dale Glass on 27/8/2022
|
||||
// Copyright 2022 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef overte_ScriptingEngineTests_h
|
||||
#define overte_ScriptingEngineTests_h
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
|
||||
|
||||
class ScriptEngineTests : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void scriptTest();
|
||||
};
|
||||
|
||||
#endif // overte_ScriptingEngineTests_h
|
Loading…
Reference in a new issue