mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Implement escargot debugger restart support
Implement restart in escargot and python debugger. Also add debugger test. Signed-off-by: Ádám László Kulcsár <adam.kulcsar@szteszoftver.hu>
This commit is contained in:
parent
7683468efb
commit
475149426f
14 changed files with 218 additions and 103 deletions
|
|
@ -1986,7 +1986,7 @@ class DebuggerC : public Debugger {
|
|||
public:
|
||||
virtual void init(const char* options, Context* context) override {}
|
||||
virtual void parseCompleted(String* source, String* srcName, size_t originLineOffset, String* error = nullptr) override;
|
||||
virtual void stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
virtual bool stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
virtual void byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock) override;
|
||||
virtual void exceptionCaught(String* message, SavedStackTraceDataVector& exceptionTrace) override;
|
||||
virtual void consoleOut(String* output) override;
|
||||
|
|
@ -2057,7 +2057,7 @@ static LexicalEnvironment* getFunctionLexEnv(ExecutionState* state)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void DebuggerC::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
bool DebuggerC::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
{
|
||||
DebuggerOperationsRef::BreakpointOperations operations(reinterpret_cast<DebuggerOperationsRef::WeakCodeRef*>(byteCodeBlock), toRef(state), offset);
|
||||
|
||||
|
|
@ -2092,6 +2092,7 @@ void DebuggerC::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset,
|
|||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebuggerC::byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock)
|
||||
|
|
@ -3442,6 +3443,24 @@ bool ContextRef::isWaitBeforeExit()
|
|||
#endif /* ESCARGOT_DEBUGGER */
|
||||
}
|
||||
|
||||
bool ContextRef::isDebuggerRestartTrue()
|
||||
{
|
||||
#ifdef ESCARGOT_DEBUGGER
|
||||
return isDebuggerRunning() && toImpl(this)->debugger()->getRestart();
|
||||
#else /* !ESCARGOT_DEBUGGER */
|
||||
return false;
|
||||
#endif /* ESCARGOT_DEBUGGER */
|
||||
}
|
||||
|
||||
void ContextRef::setDebuggerRestart()
|
||||
{
|
||||
#ifdef ESCARGOT_DEBUGGER
|
||||
if (isDebuggerRunning()) {
|
||||
toImpl(this)->debugger()->setRestart(false);
|
||||
}
|
||||
#endif /* ESCARGOT_DEBUGGER */
|
||||
}
|
||||
|
||||
void ContextRef::printDebugger(StringRef* output)
|
||||
{
|
||||
#ifdef ESCARGOT_DEBUGGER
|
||||
|
|
|
|||
|
|
@ -957,9 +957,11 @@ public:
|
|||
bool initDebugger(const char* options);
|
||||
bool isDebuggerRunning();
|
||||
bool isWaitBeforeExit();
|
||||
bool isDebuggerRestartTrue();
|
||||
void printDebugger(StringRef* output);
|
||||
void pumpDebuggerEvents();
|
||||
void setAsAlwaysStopState();
|
||||
void setDebuggerRestart();
|
||||
StringRef* getClientSource(StringRef** sourceName);
|
||||
|
||||
typedef OptionalRef<ValueRef> (*VirtualIdentifierCallback)(ExecutionStateRef* state, ValueRef* name);
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ public:
|
|||
return m_activeSavedStackTrace;
|
||||
}
|
||||
|
||||
inline void processDisabledBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
inline bool processDisabledBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
{
|
||||
if (m_stopState != ESCARGOT_DEBUGGER_ALWAYS_STOP && m_stopState != state) {
|
||||
m_delay--;
|
||||
|
|
@ -154,6 +154,8 @@ public:
|
|||
if (m_stopState == ESCARGOT_DEBUGGER_ALWAYS_STOP || m_stopState == state) {
|
||||
stopAtBreakpoint(byteCodeBlock, offset, state);
|
||||
}
|
||||
|
||||
return m_restartDebugging;
|
||||
}
|
||||
|
||||
static inline void updateStopState(Debugger* debugger, ExecutionState* state, ExecutionState* newState)
|
||||
|
|
@ -189,7 +191,7 @@ public:
|
|||
|
||||
virtual void init(const char* options, Context* context) = 0;
|
||||
virtual void parseCompleted(String* source, String* srcName, size_t originLineOffset, String* error = nullptr) = 0;
|
||||
virtual void stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) = 0;
|
||||
virtual bool stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) = 0;
|
||||
virtual void byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock) = 0;
|
||||
virtual void exceptionCaught(String* message, SavedStackTraceDataVector& exceptionTrace) = 0;
|
||||
virtual void consoleOut(String* output) = 0;
|
||||
|
|
@ -210,6 +212,16 @@ public:
|
|||
|
||||
Vector<Object*, GCUtil::gc_malloc_allocator<Object*>> m_activeObjects;
|
||||
|
||||
bool getRestart()
|
||||
{
|
||||
return m_restartDebugging;
|
||||
}
|
||||
|
||||
void setRestart(bool b)
|
||||
{
|
||||
m_restartDebugging = b;
|
||||
}
|
||||
|
||||
protected:
|
||||
Debugger()
|
||||
: m_delay(ESCARGOT_DEBUGGER_MESSAGE_PROCESS_DELAY)
|
||||
|
|
@ -234,6 +246,7 @@ protected:
|
|||
ExecutionState* m_stopState;
|
||||
std::vector<BreakpointLocationsInfo*> m_breakpointLocationsVector;
|
||||
Vector<uintptr_t, GCUtil::gc_malloc_atomic_allocator<uintptr_t>> m_releasedFunctions;
|
||||
bool m_restartDebugging;
|
||||
|
||||
private:
|
||||
Context* m_context;
|
||||
|
|
|
|||
|
|
@ -258,14 +258,14 @@ void DebuggerDevtools::sendPausedEvent(ByteCodeBlock* byteCodeBlock, const uint3
|
|||
sendMessage(msg, msg.length());
|
||||
}
|
||||
|
||||
void DebuggerDevtools::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
bool DebuggerDevtools::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
{
|
||||
if (m_stopState == ESCARGOT_DEBUGGER_IN_EVAL_MODE) {
|
||||
m_delay--;
|
||||
if (m_delay == 0) {
|
||||
processEvents(state, byteCodeBlock);
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
sendPausedEvent(byteCodeBlock, offset, state, !m_startBreakpoint);
|
||||
|
|
@ -275,7 +275,7 @@ void DebuggerDevtools::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t o
|
|||
}
|
||||
|
||||
if (!enabled()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(m_activeObjects.empty());
|
||||
|
|
@ -286,6 +286,8 @@ void DebuggerDevtools::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t o
|
|||
|
||||
m_activeObjects.clear();
|
||||
m_delay = ESCARGOT_DEBUGGER_MESSAGE_PROCESS_DELAY;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebuggerDevtools::byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
bool skipSourceCode(String* srcName) const override;
|
||||
|
||||
void parseCompleted(String* source, String* srcName, size_t originLineOffset, String* error = nullptr) override;
|
||||
void stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
bool stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
void byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock) override;
|
||||
void exceptionCaught(String* message, SavedStackTraceDataVector& exceptionTrace) override;
|
||||
void consoleOut(String* output) override;
|
||||
|
|
|
|||
|
|
@ -219,14 +219,14 @@ void DebuggerEscargot::sendVariableObjectInfo(uint8_t subType, Object* object)
|
|||
send(ESCARGOT_MESSAGE_VARIABLE, &variableObjectInfo, sizeof(VariableObjectInfo));
|
||||
}
|
||||
|
||||
void DebuggerEscargot::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
bool DebuggerEscargot::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state)
|
||||
{
|
||||
if (m_stopState == ESCARGOT_DEBUGGER_IN_EVAL_MODE) {
|
||||
m_delay--;
|
||||
if (m_delay == 0) {
|
||||
processEvents(state, byteCodeBlock);
|
||||
}
|
||||
return;
|
||||
return m_restartDebugging;
|
||||
}
|
||||
|
||||
BreakpointOffset breakpointOffset;
|
||||
|
|
@ -238,7 +238,7 @@ void DebuggerEscargot::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t o
|
|||
send(ESCARGOT_MESSAGE_BREAKPOINT_HIT, &breakpointOffset, sizeof(BreakpointOffset));
|
||||
|
||||
if (!enabled()) {
|
||||
return;
|
||||
return m_restartDebugging;
|
||||
}
|
||||
|
||||
ASSERT(m_activeObjects.size() == 0);
|
||||
|
|
@ -249,6 +249,8 @@ void DebuggerEscargot::stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t o
|
|||
|
||||
m_activeObjects.clear();
|
||||
m_delay = ESCARGOT_DEBUGGER_MESSAGE_PROCESS_DELAY;
|
||||
|
||||
return m_restartDebugging;
|
||||
}
|
||||
|
||||
void DebuggerEscargot::byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock)
|
||||
|
|
@ -899,6 +901,10 @@ bool DebuggerEscargot::processEvents(ExecutionState* state, Optional<ByteCodeBlo
|
|||
m_stopState = stopState;
|
||||
return false;
|
||||
}
|
||||
case ESCARGOT_MESSAGE_RESTART: {
|
||||
setRestart(true);
|
||||
return true;
|
||||
}
|
||||
case ESCARGOT_MESSAGE_WATCH_8BIT_START:
|
||||
case ESCARGOT_MESSAGE_WATCH_16BIT_START:
|
||||
case ESCARGOT_MESSAGE_EVAL_8BIT_START:
|
||||
|
|
|
|||
|
|
@ -109,36 +109,37 @@ public:
|
|||
ESCARGOT_MESSAGE_STEP = 3,
|
||||
ESCARGOT_MESSAGE_NEXT = 4,
|
||||
ESCARGOT_MESSAGE_FINISH = 5,
|
||||
ESCARGOT_MESSAGE_RESTART = 6,
|
||||
// These four must be in the same order.
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT_START = 6,
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT = 7,
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 8,
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 9,
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT_START = 7,
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT = 8,
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 9,
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 10,
|
||||
// These four must be in the same order.
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT_START = 10,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT = 11,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT_START = 12,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT = 13,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT_START = 11,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT = 12,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT_START = 13,
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT = 14,
|
||||
// These four must be in the same order.
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT_START = 14,
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT = 15,
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT_START = 16,
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT = 17,
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 18,
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 19,
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_VARIABLES = 20,
|
||||
ESCARGOT_MESSAGE_GET_OBJECT = 21,
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT_START = 15,
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT = 16,
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT_START = 17,
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT = 18,
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 19,
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 20,
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_VARIABLES = 21,
|
||||
ESCARGOT_MESSAGE_GET_OBJECT = 22,
|
||||
// These four must be in the same order.
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT_START = 22,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT = 23,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT_START = 24,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT = 25,
|
||||
ESCARGOT_DEBUGGER_THERE_WAS_NO_SOURCE = 26,
|
||||
ESCARGOT_DEBUGGER_PENDING_CONFIG = 27,
|
||||
ESCARGOT_DEBUGGER_PENDING_RESUME = 28,
|
||||
ESCARGOT_DEBUGGER_WAIT_BEFORE_EXIT = 29,
|
||||
ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT = 30,
|
||||
ESCARGOT_DEBUGGER_STOP = 31
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT_START = 23,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT = 24,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT_START = 25,
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT = 26,
|
||||
ESCARGOT_DEBUGGER_THERE_WAS_NO_SOURCE = 27,
|
||||
ESCARGOT_DEBUGGER_PENDING_CONFIG = 28,
|
||||
ESCARGOT_DEBUGGER_PENDING_RESUME = 29,
|
||||
ESCARGOT_DEBUGGER_WAIT_BEFORE_EXIT = 30,
|
||||
ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT = 31,
|
||||
ESCARGOT_DEBUGGER_STOP = 32
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -190,7 +191,7 @@ public:
|
|||
|
||||
void init(const char* options, Context* context) override;
|
||||
void parseCompleted(String* source, String* srcName, size_t originLineOffset, String* error = nullptr) override;
|
||||
void stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
bool stopAtBreakpoint(ByteCodeBlock* byteCodeBlock, uint32_t offset, ExecutionState* state) override;
|
||||
void byteCodeReleaseNotification(ByteCodeBlock* byteCodeBlock) override;
|
||||
void exceptionCaught(String* message, SavedStackTraceDataVector& exceptionTrace) override;
|
||||
void consoleOut(String* output) override;
|
||||
|
|
|
|||
|
|
@ -763,6 +763,14 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
// Return F.[[Call]](V, argumentsList).
|
||||
registerFile[code->m_resultIndex] = callee.asPointerValue()->call(*state, Value(), code->m_argumentCount, ®isterFile[code->m_argumentsStartIndex]);
|
||||
|
||||
#ifdef ESCARGOT_DEBUGGER
|
||||
if (state->context()->debuggerEnabled()) {
|
||||
if (state->context()->debugger()->getRestart()) {
|
||||
return Value(true);
|
||||
}
|
||||
}
|
||||
#endif /* ESCARGOT_DEBUGGER */
|
||||
|
||||
ADD_PROGRAM_COUNTER(Call);
|
||||
NEXT_INSTRUCTION();
|
||||
}
|
||||
|
|
@ -1715,7 +1723,10 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
:
|
||||
{
|
||||
if (state->context()->debuggerEnabled()) {
|
||||
state->context()->debugger()->processDisabledBreakpoint(byteCodeBlock, (uint32_t)(programCounter - (size_t)byteCodeBlock->m_code.data()), state);
|
||||
bool restart = state->context()->debugger()->processDisabledBreakpoint(byteCodeBlock, (uint32_t)(programCounter - (size_t)byteCodeBlock->m_code.data()), state);
|
||||
if (restart) {
|
||||
return Value(true);
|
||||
}
|
||||
}
|
||||
|
||||
ADD_PROGRAM_COUNTER(BreakpointDisabled);
|
||||
|
|
@ -1726,7 +1737,10 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
|
|||
:
|
||||
{
|
||||
if (state->context()->debuggerEnabled()) {
|
||||
state->context()->debugger()->stopAtBreakpoint(byteCodeBlock, (uint32_t)(programCounter - (size_t)byteCodeBlock->m_code.data()), state);
|
||||
bool restart = state->context()->debugger()->stopAtBreakpoint(byteCodeBlock, (uint32_t)(programCounter - (size_t)byteCodeBlock->m_code.data()), state);
|
||||
if (restart) {
|
||||
return Value(true);
|
||||
}
|
||||
}
|
||||
|
||||
ADD_PROGRAM_COUNTER(BreakpointEnabled);
|
||||
|
|
|
|||
|
|
@ -898,48 +898,61 @@ static bool evalScript(ContextRef* context, StringRef* source, StringRef* srcNam
|
|||
isModule = isModule || true;
|
||||
}
|
||||
|
||||
auto scriptInitializeResult = context->scriptParser()->initializeScript(source, srcName, isModule);
|
||||
if (!scriptInitializeResult.script) {
|
||||
fprintf(stderr, "Script parsing error: ");
|
||||
switch (scriptInitializeResult.parseErrorCode) {
|
||||
case Escargot::ErrorObjectRef::Code::SyntaxError:
|
||||
fprintf(stderr, "SyntaxError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::EvalError:
|
||||
fprintf(stderr, "EvalError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::RangeError:
|
||||
fprintf(stderr, "RangeError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::ReferenceError:
|
||||
fprintf(stderr, "ReferenceError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::TypeError:
|
||||
fprintf(stderr, "TypeError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::URIError:
|
||||
fprintf(stderr, "URIError");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
bool shouldRestart = false;
|
||||
do {
|
||||
if (shouldRestart) {
|
||||
source = Evaluator::execute(context, [](ExecutionStateRef* state, StringRef* str) -> ValueRef* { return builtinHelperFileRead(state, str->toStdUTF8String().c_str(), "read").get(); }, srcName).result->asString();
|
||||
}
|
||||
fprintf(stderr, ": %s\n", scriptInitializeResult.parseErrorMessage->toStdUTF8String().data());
|
||||
return false;
|
||||
}
|
||||
shouldRestart = false;
|
||||
|
||||
auto evalResult = Evaluator::execute(context, [](ExecutionStateRef* state, ScriptRef* script) -> ValueRef* { return script->execute(state); }, scriptInitializeResult.script.get());
|
||||
|
||||
if (!evalResult.isSuccessful()) {
|
||||
fprintf(stderr, "Uncaught %s:\n", evalResult.resultOrErrorToString(context)->toStdUTF8String().data());
|
||||
for (size_t i = 0; i < evalResult.stackTrace.size(); i++) {
|
||||
fprintf(stderr, "%s (%d:%d)\n", evalResult.stackTrace[i].srcName->toStdUTF8String().data(), (int)evalResult.stackTrace[i].loc.line, (int)evalResult.stackTrace[i].loc.column);
|
||||
auto scriptInitializeResult = context->scriptParser()->initializeScript(source, srcName, isModule);
|
||||
if (!scriptInitializeResult.script) {
|
||||
fprintf(stderr, "Script parsing error: ");
|
||||
switch (scriptInitializeResult.parseErrorCode) {
|
||||
case Escargot::ErrorObjectRef::Code::SyntaxError:
|
||||
fprintf(stderr, "SyntaxError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::EvalError:
|
||||
fprintf(stderr, "EvalError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::RangeError:
|
||||
fprintf(stderr, "RangeError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::ReferenceError:
|
||||
fprintf(stderr, "ReferenceError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::TypeError:
|
||||
fprintf(stderr, "TypeError");
|
||||
break;
|
||||
case Escargot::ErrorObjectRef::Code::URIError:
|
||||
fprintf(stderr, "URIError");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, ": %s\n", scriptInitializeResult.parseErrorMessage->toStdUTF8String().data());
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shouldPrintScriptResult) {
|
||||
puts(evalResult.resultOrErrorToString(context)->toStdUTF8String().data());
|
||||
}
|
||||
auto evalResult = Evaluator::execute(context, [](ExecutionStateRef* state, ScriptRef* script) -> ValueRef* { return script->execute(state); }, scriptInitializeResult.script.get());
|
||||
if (!evalResult.isSuccessful()) {
|
||||
fprintf(stderr, "Uncaught %s:\n", evalResult.resultOrErrorToString(context)->toStdUTF8String().data());
|
||||
for (size_t i = 0; i < evalResult.stackTrace.size(); i++) {
|
||||
fprintf(stderr, "%s (%d:%d)\n", evalResult.stackTrace[i].srcName->toStdUTF8String().data(), (int)evalResult.stackTrace[i].loc.line, (int)evalResult.stackTrace[i].loc.column);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context->isDebuggerRestartTrue()) {
|
||||
shouldRestart = true;
|
||||
context->setDebuggerRestart();
|
||||
}
|
||||
|
||||
if (shouldPrintScriptResult) {
|
||||
puts(evalResult.resultOrErrorToString(context)->toStdUTF8String().data());
|
||||
}
|
||||
} while (shouldRestart);
|
||||
|
||||
bool result = true;
|
||||
while (context->vmInstance()->hasPendingJob() || context->vmInstance()->hasPendingJobFromAnotherThread()) {
|
||||
|
|
|
|||
|
|
@ -228,6 +228,12 @@ class DebuggerPrompt(Cmd):
|
|||
else:
|
||||
pprint(self.debugger.function_list)
|
||||
|
||||
def do_restart(self, args):
|
||||
""" Restart current debugging from the start of the file """
|
||||
self.debugger.send_restart()
|
||||
self.debugger.step()
|
||||
self.stop = True
|
||||
do_re = do_restart
|
||||
|
||||
def _scroll_direction(debugger, direction):
|
||||
""" Helper function for do_scroll """
|
||||
|
|
|
|||
|
|
@ -85,32 +85,33 @@ ESCARGOT_MESSAGE_CONTINUE = 2
|
|||
ESCARGOT_MESSAGE_STEP = 3
|
||||
ESCARGOT_MESSAGE_NEXT = 4
|
||||
ESCARGOT_MESSAGE_FINISH = 5
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT_START = 6
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT = 7
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 8
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 9
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT_START = 10
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT = 11
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT_START = 12
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT = 13
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT_START = 14
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT = 15
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT_START = 16
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT = 17
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 18
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 19
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_VARIABLES = 20
|
||||
ESCARGOT_MESSAGE_GET_OBJECT = 21
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT_START = 22
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT = 23
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT_START = 24
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT = 25
|
||||
ESCARGOT_DEBUGGER_THERE_WAS_NO_SOURCE = 26
|
||||
ESCARGOT_DEBUGGER_PENDING_CONFIG = 27
|
||||
ESCARGOT_DEBUGGER_PENDING_RESUME = 28
|
||||
ESCARGOT_DEBUGGER_WAIT_BEFORE_EXIT = 29
|
||||
ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT = 30
|
||||
ESCARGOT_DEBUGGER_STOP = 31
|
||||
ESCARGOT_MESSAGE_RESTART = 6
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT_START = 7
|
||||
ESCARGOT_MESSAGE_EVAL_8BIT = 8
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 9
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 10
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT_START = 11
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_8BIT = 12
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT_START = 13
|
||||
ESCARGOT_MESSAGE_EVAL_WITHOUT_STOP_16BIT = 14
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT_START = 15
|
||||
ESCARGOT_MESSAGE_WATCH_8BIT = 16
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT_START = 17
|
||||
ESCARGOT_MESSAGE_WATCH_16BIT = 18
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 19
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 20
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_VARIABLES = 21
|
||||
ESCARGOT_MESSAGE_GET_OBJECT = 22
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT_START = 23
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_8BIT = 24
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT_START = 25
|
||||
ESCARGOT_DEBUGGER_CLIENT_SOURCE_16BIT = 26
|
||||
ESCARGOT_DEBUGGER_THERE_WAS_NO_SOURCE = 27
|
||||
ESCARGOT_DEBUGGER_PENDING_CONFIG = 28
|
||||
ESCARGOT_DEBUGGER_PENDING_RESUME = 29
|
||||
ESCARGOT_DEBUGGER_WAIT_BEFORE_EXIT = 30
|
||||
ESCARGOT_DEBUGGER_TAKE_HEAP_SNAPSHOT = 31
|
||||
ESCARGOT_DEBUGGER_STOP = 32
|
||||
|
||||
|
||||
# Environment record types
|
||||
|
|
@ -638,6 +639,10 @@ class Debugger(object):
|
|||
command_id)
|
||||
self.channel.send_message(self.byte_order, message)
|
||||
|
||||
def send_restart(self):
|
||||
self.prompt = False
|
||||
self._exec_command(ESCARGOT_MESSAGE_RESTART)
|
||||
|
||||
def do_continue(self):
|
||||
self.prompt = False
|
||||
self._exec_command(ESCARGOT_MESSAGE_CONTINUE)
|
||||
|
|
|
|||
6
tools/debugger/tests/do_restart.cmd
Normal file
6
tools/debugger/tests/do_restart.cmd
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
s
|
||||
restart
|
||||
n
|
||||
s
|
||||
re
|
||||
c
|
||||
18
tools/debugger/tests/do_restart.expected
Normal file
18
tools/debugger/tests/do_restart.expected
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Connecting to: localhost:6501
|
||||
Connection created!!!
|
||||
Stopped at tools/debugger/tests/do_restart.js:9
|
||||
(escargot-debugger) s
|
||||
Stopped at tools/debugger/tests/do_restart.js:2 (in hello() at line:1, col:1)
|
||||
(escargot-debugger) restart
|
||||
Stopped at tools/debugger/tests/do_restart.js:9
|
||||
(escargot-debugger) n
|
||||
Print: Hello world!
|
||||
Stopped at tools/debugger/tests/do_restart.js:10
|
||||
(escargot-debugger) s
|
||||
Stopped at tools/debugger/tests/do_restart.js:6 (in bye() at line:5, col:1)
|
||||
(escargot-debugger) re
|
||||
Stopped at tools/debugger/tests/do_restart.js:9
|
||||
(escargot-debugger) c
|
||||
Print: Hello world!
|
||||
Print: Bye world!
|
||||
Connection closed.
|
||||
10
tools/debugger/tests/do_restart.js
Normal file
10
tools/debugger/tests/do_restart.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
function hello() {
|
||||
print("Hello world!");
|
||||
}
|
||||
|
||||
function bye() {
|
||||
print("Bye world!");
|
||||
}
|
||||
|
||||
hello();
|
||||
bye();
|
||||
Loading…
Add table
Add a link
Reference in a new issue