mirror of
https://github.com/overte-org/overte.git
synced 2025-07-26 05:13:47 +02:00
V8 fixes, including making debug console work
This commit is contained in:
parent
797d92d5dc
commit
0c9a403313
6 changed files with 77 additions and 46 deletions
|
@ -351,12 +351,12 @@ void JSConsole::executeCommand(const QString& command) {
|
||||||
|
|
||||||
std::weak_ptr<ScriptManager> weakScriptManager = _scriptManager;
|
std::weak_ptr<ScriptManager> weakScriptManager = _scriptManager;
|
||||||
auto consoleFileName = _consoleFileName;
|
auto consoleFileName = _consoleFileName;
|
||||||
QFuture<ScriptValue> future = QtConcurrent::run([weakScriptManager, consoleFileName, command]() -> ScriptValue {
|
QFuture<QVariant> future = QtConcurrent::run([weakScriptManager, consoleFileName, command]() -> QVariant {
|
||||||
ScriptValue result;
|
QVariant result;
|
||||||
auto scriptManager = weakScriptManager.lock();
|
auto scriptManager = weakScriptManager.lock();
|
||||||
if (scriptManager) {
|
if (scriptManager) {
|
||||||
BLOCKING_INVOKE_METHOD(scriptManager.get(), [&scriptManager, &consoleFileName, &command, &result]() -> void {
|
BLOCKING_INVOKE_METHOD(scriptManager.get(), [&scriptManager, &consoleFileName, &command, &result]() -> void {
|
||||||
result = scriptManager->evaluate(command, consoleFileName);
|
result = scriptManager->evaluate(command, consoleFileName).toVariant();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -365,7 +365,7 @@ void JSConsole::executeCommand(const QString& command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSConsole::commandFinished() {
|
void JSConsole::commandFinished() {
|
||||||
ScriptValue result = _executeWatcher.result();
|
QVariant result = _executeWatcher.result();
|
||||||
|
|
||||||
_ui->promptTextEdit->setDisabled(false);
|
_ui->promptTextEdit->setDisabled(false);
|
||||||
|
|
||||||
|
@ -374,9 +374,12 @@ void JSConsole::commandFinished() {
|
||||||
_ui->promptTextEdit->setFocus();
|
_ui->promptTextEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError());
|
// V8TODO:
|
||||||
QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND;
|
//bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError());
|
||||||
QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE;
|
//QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND;
|
||||||
|
//QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE;
|
||||||
|
QString gutter = GUTTER_PREVIOUS_COMMAND;
|
||||||
|
QString resultColor = RESULT_SUCCESS_STYLE;
|
||||||
QString resultStr = "<span style='" + resultColor + "'>" + result.toString().toHtmlEscaped() + "</span>";
|
QString resultStr = "<span style='" + resultColor + "'>" + result.toString().toHtmlEscaped() + "</span>";
|
||||||
appendMessage(gutter, resultStr);
|
appendMessage(gutter, resultStr);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ private:
|
||||||
|
|
||||||
QStandardItemModel* getAutoCompleteModel(const QString& memberOf = nullptr);
|
QStandardItemModel* getAutoCompleteModel(const QString& memberOf = nullptr);
|
||||||
|
|
||||||
QFutureWatcher<ScriptValue> _executeWatcher;
|
QFutureWatcher<QVariant> _executeWatcher;
|
||||||
Ui::Console* _ui;
|
Ui::Console* _ui;
|
||||||
int _currentCommandInHistory;
|
int _currentCommandInHistory;
|
||||||
QString _savedHistoryFilename;
|
QString _savedHistoryFilename;
|
||||||
|
|
|
@ -1968,7 +1968,9 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SANITY/PERFORMANCE CHECK USING SANDBOX
|
// SANITY/PERFORMANCE CHECK USING SANDBOX
|
||||||
const int SANDBOX_TIMEOUT = 0.25 * MSECS_PER_SECOND;
|
// V8TODO: can be skipped for now but needs to be implemented before release
|
||||||
|
|
||||||
|
/*const int SANDBOX_TIMEOUT = 0.25 * MSECS_PER_SECOND;
|
||||||
ScriptEnginePointer sandbox = newScriptEngine();
|
ScriptEnginePointer sandbox = newScriptEngine();
|
||||||
sandbox->setProcessEventsInterval(SANDBOX_TIMEOUT);
|
sandbox->setProcessEventsInterval(SANDBOX_TIMEOUT);
|
||||||
ScriptValue testConstructor, exception;
|
ScriptValue testConstructor, exception;
|
||||||
|
@ -2104,7 +2106,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c
|
||||||
setError("Could not find constructor (" + testConstructorType + ")", EntityScriptStatus::ERROR_RUNNING_SCRIPT);
|
setError("Could not find constructor (" + testConstructorType + ")", EntityScriptStatus::ERROR_RUNNING_SCRIPT);
|
||||||
emit unhandledException(err);
|
emit unhandledException(err);
|
||||||
return; // done processing script
|
return; // done processing script
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// (this feeds into refreshFileScript)
|
// (this feeds into refreshFileScript)
|
||||||
int64_t lastModified = 0;
|
int64_t lastModified = 0;
|
||||||
|
|
|
@ -119,7 +119,7 @@ ScriptFunctionContextPointer ScriptContextV8Wrapper::functionContext() const {
|
||||||
|
|
||||||
ScriptContextPointer ScriptContextV8Wrapper::parentContext() const {
|
ScriptContextPointer ScriptContextV8Wrapper::parentContext() const {
|
||||||
//V8TODO
|
//V8TODO
|
||||||
Q_ASSERT(false);
|
//Q_ASSERT(false);
|
||||||
//V8ScriptContext* result = _context->parentContext();
|
//V8ScriptContext* result = _context->parentContext();
|
||||||
//return result ? std::make_shared<ScriptContextV8Wrapper>(_engine, result) : ScriptContextPointer();
|
//return result ? std::make_shared<ScriptContextV8Wrapper>(_engine, result) : ScriptContextPointer();
|
||||||
return ScriptContextPointer();
|
return ScriptContextPointer();
|
||||||
|
|
|
@ -981,28 +981,42 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
}
|
}
|
||||||
Q_ASSERT(!isEvaluating());
|
Q_ASSERT(!isEvaluating());
|
||||||
_isEvaluating = true;
|
_isEvaluating = true;
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
bool is_isolate_exit_needed = false;
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||||
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||||
if (!unwrapped) {
|
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||||
auto err = makeError(newValue("could not unwrap program"));
|
_v8Isolate->Enter();
|
||||||
raiseException(err);
|
is_isolate_exit_needed = true;
|
||||||
maybeEmitUncaughtException("compile");
|
|
||||||
_isEvaluating = false;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
|
|
||||||
if (syntaxCheck->state() == ScriptSyntaxCheckResult::Error) {
|
|
||||||
auto err = makeError(newValue(syntaxCheck->errorMessage()));
|
|
||||||
raiseException(err);
|
|
||||||
maybeEmitUncaughtException("compile");
|
|
||||||
_isEvaluating = false;
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
ScriptValue errorValue;
|
||||||
|
ScriptValue resultValue;
|
||||||
|
bool hasFailed = false;
|
||||||
|
{
|
||||||
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
|
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
||||||
|
if (!unwrapped) {
|
||||||
|
errorValue = makeError(newValue("could not unwrap program"));
|
||||||
|
raiseException(errorValue);
|
||||||
|
maybeEmitUncaughtException("compile");
|
||||||
|
hasFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
const V8ScriptProgram& v8Program = unwrapped->toV8Value();
|
if(!hasFailed) {
|
||||||
// V8TODO
|
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
|
||||||
/*if (qProgram.isNull()) {
|
if (syntaxCheck->state() == ScriptSyntaxCheckResult::Error) {
|
||||||
|
errorValue = makeError(newValue(syntaxCheck->errorMessage()));
|
||||||
|
raiseException(errorValue);
|
||||||
|
maybeEmitUncaughtException("compile");
|
||||||
|
hasFailed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> result;
|
||||||
|
if(!hasFailed) {
|
||||||
|
const V8ScriptProgram& v8Program = unwrapped->toV8Value();
|
||||||
|
// V8TODO
|
||||||
|
/*if (qProgram.isNull()) {
|
||||||
// can this happen?
|
// can this happen?
|
||||||
auto err = makeError(newValue("requested program is empty"));
|
auto err = makeError(newValue("requested program is empty"));
|
||||||
raiseException(err);
|
raiseException(err);
|
||||||
|
@ -1010,20 +1024,31 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
||||||
return err;
|
return err;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
v8::Local<v8::Value> result;
|
v8::TryCatch tryCatchRun(getIsolate());
|
||||||
v8::TryCatch tryCatchRun(getIsolate());
|
if (!v8Program.constGet()->Run(getContext()).ToLocal(&result)) {
|
||||||
if (!v8Program.constGet()->Run(getContext()).ToLocal(&result)) {
|
Q_ASSERT(tryCatchRun.HasCaught());
|
||||||
Q_ASSERT(tryCatchRun.HasCaught());
|
auto runError = tryCatchRun.Message();
|
||||||
auto runError = tryCatchRun.Message();
|
errorValue = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
||||||
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
raiseException(errorValue);
|
||||||
raiseException(errorValue);
|
maybeEmitUncaughtException("evaluate");
|
||||||
maybeEmitUncaughtException("evaluate");
|
hasFailed = true;
|
||||||
_isEvaluating = false;
|
}
|
||||||
return errorValue;
|
}
|
||||||
|
if(!hasFailed) {
|
||||||
|
V8ScriptValue resultValueV8(_v8Isolate, result);
|
||||||
|
resultValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValueV8)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
V8ScriptValue resultValue(_v8Isolate, result);
|
|
||||||
_isEvaluating = false;
|
_isEvaluating = false;
|
||||||
return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue)));
|
if (is_isolate_exit_needed) {
|
||||||
|
_v8Isolate->Exit();
|
||||||
|
_v8Locker.reset(nullptr);
|
||||||
|
}
|
||||||
|
if (hasFailed) {
|
||||||
|
return errorValue;
|
||||||
|
} else {
|
||||||
|
return resultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1094,6 +1119,7 @@ ScriptProgramPointer ScriptEngineV8::newProgram(const QString& sourceCode, const
|
||||||
//V8TODO: is it used between isolates?
|
//V8TODO: is it used between isolates?
|
||||||
//V8TODO: should it be compiled on creation?
|
//V8TODO: should it be compiled on creation?
|
||||||
//V8ScriptProgram result(sourceCode, fileName);
|
//V8ScriptProgram result(sourceCode, fileName);
|
||||||
|
|
||||||
v8::HandleScope handleScope(_v8Isolate);
|
v8::HandleScope handleScope(_v8Isolate);
|
||||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||||
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
|
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
|
||||||
|
|
|
@ -429,9 +429,9 @@ bool ScriptValueV8Wrapper::isBool() const {
|
||||||
|
|
||||||
bool ScriptValueV8Wrapper::isError() const {
|
bool ScriptValueV8Wrapper::isError() const {
|
||||||
auto isolate = _engine->getIsolate();
|
auto isolate = _engine->getIsolate();
|
||||||
Q_ASSERT(isolate->IsCurrent());
|
// Q_ASSERT(isolate->IsCurrent());
|
||||||
v8::HandleScope handleScope(isolate);
|
// v8::HandleScope handleScope(isolate);
|
||||||
v8::Context::Scope contextScope(_engine->getContext());
|
// v8::Context::Scope contextScope(_engine->getContext());
|
||||||
//V8TODO
|
//V8TODO
|
||||||
return false;
|
return false;
|
||||||
//return _value.constGet()->IsError();
|
//return _value.constGet()->IsError();
|
||||||
|
|
Loading…
Reference in a new issue