mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Support getting scope chain in the Debugger.
Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
8de35fd707
commit
a7a24cf22e
4 changed files with 132 additions and 11 deletions
|
|
@ -22,6 +22,8 @@
|
|||
#include "DebuggerTcp.h"
|
||||
#include "interpreter/ByteCode.h"
|
||||
#include "runtime/Context.h"
|
||||
#include "runtime/Environment.h"
|
||||
#include "runtime/EnvironmentRecord.h"
|
||||
#include "runtime/GlobalObject.h"
|
||||
#include "runtime/SandBox.h"
|
||||
#include "parser/Script.h"
|
||||
|
|
@ -254,6 +256,13 @@ bool Debugger::processIncomingMessages(ExecutionState* state, ByteCodeBlock* byt
|
|||
getBacktrace(state, minDepth, maxDepth, buffer[1 + sizeof(uint32_t) + sizeof(uint32_t)] != 0);
|
||||
return true;
|
||||
}
|
||||
case ESCARGOT_MESSAGE_GET_SCOPE_CHAIN: {
|
||||
if (length != 1 || m_stopState != ESCARGOT_DEBUGGER_IN_WAIT_MODE) {
|
||||
break;
|
||||
}
|
||||
getScopeChain(state);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ESCARGOT_LOG_ERROR("Invalid message received. Closing connection.\n");
|
||||
|
|
@ -384,6 +393,50 @@ void Debugger::getBacktrace(ExecutionState* state, uint32_t minDepth, uint32_t m
|
|||
}
|
||||
}
|
||||
|
||||
void Debugger::getScopeChain(ExecutionState* state)
|
||||
{
|
||||
const size_t maxMessageLength = ESCARGOT_DEBUGGER_MAX_MESSAGE_LENGTH - 1;
|
||||
uint8_t buffer[maxMessageLength];
|
||||
size_t nextScope = 0;
|
||||
|
||||
LexicalEnvironment* lexEnv = state->lexicalEnvironment();
|
||||
|
||||
while (lexEnv) {
|
||||
EnvironmentRecord* record = lexEnv->record();
|
||||
uint8_t type;
|
||||
|
||||
if (nextScope >= maxMessageLength) {
|
||||
if (!send(ESCARGOT_MESSAGE_SCOPE_CHAIN, buffer, maxMessageLength)) {
|
||||
return;
|
||||
}
|
||||
nextScope = 0;
|
||||
}
|
||||
|
||||
|
||||
if (record->isGlobalEnvironmentRecord()) {
|
||||
type = ESCARGOT_RECORD_GLOBAL_ENVIRONMENT;
|
||||
} else if (record->isDeclarativeEnvironmentRecord()) {
|
||||
DeclarativeEnvironmentRecord* declarativeRecord = record->asDeclarativeEnvironmentRecord();
|
||||
if (declarativeRecord->isFunctionEnvironmentRecord()) {
|
||||
type = ESCARGOT_RECORD_FUNCTION_ENVIRONMENT;
|
||||
} else {
|
||||
type = ESCARGOT_RECORD_DECLARATIVE_ENVIRONMENT;
|
||||
}
|
||||
} else if (record->isObjectEnvironmentRecord()) {
|
||||
type = ESCARGOT_RECORD_OBJECT_ENVIRONMENT;
|
||||
} else if (record->isModuleEnvironmentRecord()) {
|
||||
type = ESCARGOT_RECORD_MODULE_ENVIRONMENT;
|
||||
} else {
|
||||
type = ESCARGOT_RECORD_UNKNOWN_ENVIRONMENT;
|
||||
}
|
||||
|
||||
buffer[nextScope++] = type;
|
||||
lexEnv = lexEnv->outerEnvironment();
|
||||
}
|
||||
|
||||
send(ESCARGOT_MESSAGE_SCOPE_CHAIN_END, buffer, nextScope);
|
||||
}
|
||||
|
||||
Debugger* createDebugger(const char* options, bool* debuggerEnabled)
|
||||
{
|
||||
Debugger* debugger = new DebuggerTcp();
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public:
|
|||
ESCARGOT_MESSAGE_BACKTRACE_8BIT_END = 32,
|
||||
ESCARGOT_MESSAGE_BACKTRACE_16BIT = 33,
|
||||
ESCARGOT_MESSAGE_BACKTRACE_16BIT_END = 34,
|
||||
ESCARGOT_MESSAGE_SCOPE_CHAIN = 35,
|
||||
ESCARGOT_MESSAGE_SCOPE_CHAIN_END = 36,
|
||||
};
|
||||
|
||||
// Messages sent by the debugger client to Escargot
|
||||
|
|
@ -100,6 +102,17 @@ public:
|
|||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 7,
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 8,
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 9,
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 10,
|
||||
};
|
||||
|
||||
// Environment record types
|
||||
enum {
|
||||
ESCARGOT_RECORD_GLOBAL_ENVIRONMENT = 0,
|
||||
ESCARGOT_RECORD_FUNCTION_ENVIRONMENT = 1,
|
||||
ESCARGOT_RECORD_DECLARATIVE_ENVIRONMENT = 2,
|
||||
ESCARGOT_RECORD_OBJECT_ENVIRONMENT = 3,
|
||||
ESCARGOT_RECORD_MODULE_ENVIRONMENT = 4,
|
||||
ESCARGOT_RECORD_UNKNOWN_ENVIRONMENT = 5,
|
||||
};
|
||||
|
||||
struct BreakpointLocation {
|
||||
|
|
@ -175,6 +188,7 @@ protected:
|
|||
bool processIncomingMessages(ExecutionState* state, ByteCodeBlock* byteCodeBlock);
|
||||
bool doEval(ExecutionState* state, ByteCodeBlock* byteCodeBlock, uint8_t* buffer, size_t length);
|
||||
void getBacktrace(ExecutionState* state, uint32_t minDepth, uint32_t maxDepth, bool getTotal);
|
||||
void getScopeChain(ExecutionState* state);
|
||||
|
||||
bool* m_debuggerEnabled;
|
||||
bool m_enabled;
|
||||
|
|
|
|||
|
|
@ -159,6 +159,11 @@ class DebuggerPrompt(Cmd):
|
|||
self.stop = True
|
||||
do_bt = do_backtrace
|
||||
|
||||
def do_scope(self, _):
|
||||
""" Get lexical environment chain """
|
||||
self.debugger.scope_chain()
|
||||
self.stop = True
|
||||
|
||||
def do_dump(self, args):
|
||||
""" Dump all of the debugger data """
|
||||
if args:
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ ESCARGOT_MESSAGE_BACKTRACE_8BIT = 31
|
|||
ESCARGOT_MESSAGE_BACKTRACE_8BIT_END = 32
|
||||
ESCARGOT_MESSAGE_BACKTRACE_16BIT = 33
|
||||
ESCARGOT_MESSAGE_BACKTRACE_16BIT_END = 34
|
||||
ESCARGOT_MESSAGE_SCOPE_CHAIN = 35
|
||||
ESCARGOT_MESSAGE_SCOPE_CHAIN_END = 36
|
||||
|
||||
|
||||
# Messages sent by the debugger client to Escargot.
|
||||
|
|
@ -74,6 +76,16 @@ ESCARGOT_MESSAGE_EVAL_8BIT = 6
|
|||
ESCARGOT_MESSAGE_EVAL_16BIT_START = 7
|
||||
ESCARGOT_MESSAGE_EVAL_16BIT = 8
|
||||
ESCARGOT_MESSAGE_GET_BACKTRACE = 9
|
||||
ESCARGOT_MESSAGE_GET_SCOPE_CHAIN = 10
|
||||
|
||||
|
||||
# Environment record types
|
||||
ESCARGOT_RECORD_GLOBAL_ENVIRONMENT = 0
|
||||
ESCARGOT_RECORD_FUNCTION_ENVIRONMENT = 1
|
||||
ESCARGOT_RECORD_DECLARATIVE_ENVIRONMENT = 2
|
||||
ESCARGOT_RECORD_OBJECT_ENVIRONMENT = 3
|
||||
ESCARGOT_RECORD_MODULE_ENVIRONMENT = 4
|
||||
ESCARGOT_RECORD_UNKNOWN_ENVIRONMENT = 5
|
||||
|
||||
|
||||
def arguments_parse():
|
||||
|
|
@ -344,6 +356,20 @@ class Debugger(object):
|
|||
result += "Total number of frames: %d\n" % (total)
|
||||
return DebuggerAction(DebuggerAction.TEXT, result)
|
||||
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_EVAL_RESULT_8BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_8BIT_END,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_16BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_16BIT_END]:
|
||||
self.prompt = True
|
||||
return self._receive_string(ESCARGOT_MESSAGE_EVAL_RESULT_8BIT, "", data);
|
||||
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_EVAL_FAILED_8BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_8BIT_END,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_16BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_16BIT_END]:
|
||||
self.prompt = True
|
||||
return self._receive_string(ESCARGOT_MESSAGE_EVAL_FAILED_8BIT, self.red + "Exception: ", data);
|
||||
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_BACKTRACE_8BIT,
|
||||
ESCARGOT_MESSAGE_BACKTRACE_8BIT_END,
|
||||
ESCARGOT_MESSAGE_BACKTRACE_16BIT,
|
||||
|
|
@ -369,19 +395,38 @@ class Debugger(object):
|
|||
self.prompt = True
|
||||
return DebuggerAction(DebuggerAction.TEXT, backtrace.replace("\0", "\n"))
|
||||
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_EVAL_RESULT_8BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_8BIT_END,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_16BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_RESULT_16BIT_END]:
|
||||
self.prompt = True
|
||||
return self._receive_string(ESCARGOT_MESSAGE_EVAL_RESULT_8BIT, "", data);
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_SCOPE_CHAIN,
|
||||
ESCARGOT_MESSAGE_SCOPE_CHAIN_END]:
|
||||
scope_chain = ""
|
||||
|
||||
while buffer_type == ESCARGOT_MESSAGE_SCOPE_CHAIN:
|
||||
scope_chain += data[1:]
|
||||
data = self.channel.get_message(True)
|
||||
buffer_type = ord(data[0])
|
||||
|
||||
if buffer_type != ESCARGOT_MESSAGE_SCOPE_CHAIN_END:
|
||||
raise Exception("Unexpected message")
|
||||
|
||||
scope_chain += data[1:]
|
||||
result = ""
|
||||
|
||||
for env_type in scope_chain:
|
||||
env_type = ord(env_type)
|
||||
if env_type == ESCARGOT_RECORD_GLOBAL_ENVIRONMENT:
|
||||
result += "Global Environment\n"
|
||||
elif env_type == ESCARGOT_RECORD_FUNCTION_ENVIRONMENT:
|
||||
result += "Function Environment\n"
|
||||
elif env_type == ESCARGOT_RECORD_DECLARATIVE_ENVIRONMENT:
|
||||
result += "Declarative Environment\n"
|
||||
elif env_type == ESCARGOT_RECORD_OBJECT_ENVIRONMENT:
|
||||
result += "Object Environment\n"
|
||||
elif env_type == ESCARGOT_RECORD_MODULE_ENVIRONMENT:
|
||||
result += "Module Environment\n"
|
||||
else:
|
||||
result += "Unknown Environment\n"
|
||||
|
||||
elif buffer_type in [ESCARGOT_MESSAGE_EVAL_FAILED_8BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_8BIT_END,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_16BIT,
|
||||
ESCARGOT_MESSAGE_EVAL_FAILED_16BIT_END]:
|
||||
self.prompt = True
|
||||
return self._receive_string(ESCARGOT_MESSAGE_EVAL_FAILED_8BIT, self.red + "Exception: ", data);
|
||||
return DebuggerAction(DebuggerAction.TEXT, result)
|
||||
|
||||
else:
|
||||
raise Exception("Unknown message: %d" % (buffer_type))
|
||||
|
|
@ -553,6 +598,10 @@ class Debugger(object):
|
|||
self.prompt = False
|
||||
return ""
|
||||
|
||||
def scope_chain(self):
|
||||
self.prompt = False
|
||||
self._exec_command(ESCARGOT_MESSAGE_GET_SCOPE_CHAIN)
|
||||
|
||||
# pylint: disable=too-many-branches,too-many-locals,too-many-statements
|
||||
def _parse_source(self, data):
|
||||
source = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue