mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 12:02:25 +02:00
V8 fixes, including making debug console work
This commit is contained in:
parent
97137c7b13
commit
0d454eb6e8
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;
|
||||
auto consoleFileName = _consoleFileName;
|
||||
QFuture<ScriptValue> future = QtConcurrent::run([weakScriptManager, consoleFileName, command]() -> ScriptValue {
|
||||
ScriptValue result;
|
||||
QFuture<QVariant> future = QtConcurrent::run([weakScriptManager, consoleFileName, command]() -> QVariant {
|
||||
QVariant result;
|
||||
auto scriptManager = weakScriptManager.lock();
|
||||
if (scriptManager) {
|
||||
BLOCKING_INVOKE_METHOD(scriptManager.get(), [&scriptManager, &consoleFileName, &command, &result]() -> void {
|
||||
result = scriptManager->evaluate(command, consoleFileName);
|
||||
result = scriptManager->evaluate(command, consoleFileName).toVariant();
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
@ -365,7 +365,7 @@ void JSConsole::executeCommand(const QString& command) {
|
|||
}
|
||||
|
||||
void JSConsole::commandFinished() {
|
||||
ScriptValue result = _executeWatcher.result();
|
||||
QVariant result = _executeWatcher.result();
|
||||
|
||||
_ui->promptTextEdit->setDisabled(false);
|
||||
|
||||
|
@ -374,9 +374,12 @@ void JSConsole::commandFinished() {
|
|||
_ui->promptTextEdit->setFocus();
|
||||
}
|
||||
|
||||
bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError());
|
||||
QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND;
|
||||
QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE;
|
||||
// V8TODO:
|
||||
//bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError());
|
||||
//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>";
|
||||
appendMessage(gutter, resultStr);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
|
||||
QStandardItemModel* getAutoCompleteModel(const QString& memberOf = nullptr);
|
||||
|
||||
QFutureWatcher<ScriptValue> _executeWatcher;
|
||||
QFutureWatcher<QVariant> _executeWatcher;
|
||||
Ui::Console* _ui;
|
||||
int _currentCommandInHistory;
|
||||
QString _savedHistoryFilename;
|
||||
|
|
|
@ -1968,7 +1968,9 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c
|
|||
}
|
||||
|
||||
// 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();
|
||||
sandbox->setProcessEventsInterval(SANDBOX_TIMEOUT);
|
||||
ScriptValue testConstructor, exception;
|
||||
|
@ -2104,7 +2106,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c
|
|||
setError("Could not find constructor (" + testConstructorType + ")", EntityScriptStatus::ERROR_RUNNING_SCRIPT);
|
||||
emit unhandledException(err);
|
||||
return; // done processing script
|
||||
}
|
||||
}*/
|
||||
|
||||
// (this feeds into refreshFileScript)
|
||||
int64_t lastModified = 0;
|
||||
|
|
|
@ -119,7 +119,7 @@ ScriptFunctionContextPointer ScriptContextV8Wrapper::functionContext() const {
|
|||
|
||||
ScriptContextPointer ScriptContextV8Wrapper::parentContext() const {
|
||||
//V8TODO
|
||||
Q_ASSERT(false);
|
||||
//Q_ASSERT(false);
|
||||
//V8ScriptContext* result = _context->parentContext();
|
||||
//return result ? std::make_shared<ScriptContextV8Wrapper>(_engine, result) : ScriptContextPointer();
|
||||
return ScriptContextPointer();
|
||||
|
|
|
@ -981,28 +981,42 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
|||
}
|
||||
Q_ASSERT(!isEvaluating());
|
||||
_isEvaluating = true;
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program);
|
||||
if (!unwrapped) {
|
||||
auto err = makeError(newValue("could not unwrap program"));
|
||||
raiseException(err);
|
||||
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;
|
||||
bool is_isolate_exit_needed = false;
|
||||
if(!_v8Isolate->IsCurrent() && !_v8Locker) {
|
||||
// V8TODO: Theoretically only script thread should access this, so it should be safe
|
||||
_v8Locker.reset(new v8::Locker(_v8Isolate));
|
||||
_v8Isolate->Enter();
|
||||
is_isolate_exit_needed = true;
|
||||
}
|
||||
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();
|
||||
// V8TODO
|
||||
/*if (qProgram.isNull()) {
|
||||
if(!hasFailed) {
|
||||
ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax();
|
||||
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?
|
||||
auto err = makeError(newValue("requested program is empty"));
|
||||
raiseException(err);
|
||||
|
@ -1010,20 +1024,31 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro
|
|||
return err;
|
||||
}*/
|
||||
|
||||
v8::Local<v8::Value> result;
|
||||
v8::TryCatch tryCatchRun(getIsolate());
|
||||
if (!v8Program.constGet()->Run(getContext()).ToLocal(&result)) {
|
||||
Q_ASSERT(tryCatchRun.HasCaught());
|
||||
auto runError = tryCatchRun.Message();
|
||||
ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
||||
raiseException(errorValue);
|
||||
maybeEmitUncaughtException("evaluate");
|
||||
_isEvaluating = false;
|
||||
return errorValue;
|
||||
v8::TryCatch tryCatchRun(getIsolate());
|
||||
if (!v8Program.constGet()->Run(getContext()).ToLocal(&result)) {
|
||||
Q_ASSERT(tryCatchRun.HasCaught());
|
||||
auto runError = tryCatchRun.Message();
|
||||
errorValue = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(_v8Isolate, runError->Get())));
|
||||
raiseException(errorValue);
|
||||
maybeEmitUncaughtException("evaluate");
|
||||
hasFailed = true;
|
||||
}
|
||||
}
|
||||
if(!hasFailed) {
|
||||
V8ScriptValue resultValueV8(_v8Isolate, result);
|
||||
resultValue = ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValueV8)));
|
||||
}
|
||||
}
|
||||
V8ScriptValue resultValue(_v8Isolate, result);
|
||||
_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: should it be compiled on creation?
|
||||
//V8ScriptProgram result(sourceCode, fileName);
|
||||
|
||||
v8::HandleScope handleScope(_v8Isolate);
|
||||
v8::Context::Scope contextScope(_v8Context.Get(_v8Isolate));
|
||||
return std::make_shared<ScriptProgramV8Wrapper>(this, sourceCode, fileName);
|
||||
|
|
|
@ -429,9 +429,9 @@ 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());
|
||||
// Q_ASSERT(isolate->IsCurrent());
|
||||
// v8::HandleScope handleScope(isolate);
|
||||
// v8::Context::Scope contextScope(_engine->getContext());
|
||||
//V8TODO
|
||||
return false;
|
||||
//return _value.constGet()->IsError();
|
||||
|
|
Loading…
Reference in a new issue