aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Sipka <rsipka.uszeged@partner.samsung.com>2018-10-02 16:18:05 +0200
committerRobert Sipka <rsipka.uszeged@partner.samsung.com>2018-10-02 16:18:05 +0200
commit008bddc20346ba86bcdbb6bfe7865e3d19269e83 (patch)
tree40b2de3dc1b167c16504f24e3c8e0afda6df7fd8
parent7717d2ee27723b9452d98f4b5082e03ca685cf85 (diff)
List scope chain levels and their variables to the selected stack frame.variables_list
It supports to list the scope chain of the current execution context and see which variables are available. JerryScript-DCO-1.0-Signed-off-by: Robert Sipka rsipka.uszeged@partner.samsung.com
-rw-r--r--jerry-core/debugger/debugger.c277
-rw-r--r--jerry-core/debugger/debugger.h54
-rwxr-xr-xjerry-debugger/jerry_client.py12
-rw-r--r--jerry-debugger/jerry_client_ws.py141
-rwxr-xr-xtools/apt-get-install-deps.sh2
5 files changed, 477 insertions, 9 deletions
diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c
index 3f9ed5b4..ef524702 100644
--- a/jerry-core/debugger/debugger.c
+++ b/jerry-core/debugger/debugger.c
@@ -18,6 +18,7 @@
#include "ecma-builtin-helpers.h"
#include "ecma-conversion.h"
#include "ecma-eval.h"
+#include "ecma-function-object.h"
#include "ecma-objects.h"
#include "jcontext.h"
#include "jerryscript-port.h"
@@ -37,9 +38,9 @@ typedef struct
* The number of message types in the debugger should reflect the
* debugger versioning.
*/
-JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 28
- && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 19
- && JERRY_DEBUGGER_VERSION == 6,
+JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 31
+ && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 21
+ && JERRY_DEBUGGER_VERSION == 7,
debugger_version_correlates_to_message_type_count);
/**
@@ -195,6 +196,258 @@ jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the
jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + message_size);
} /* jerry_debugger_send_backtrace */
+
+/**
+ * Send the scope chain.
+ */
+static void
+jerry_debugger_send_scope_chain (void)
+{
+ vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
+
+ size_t count = 0;
+ const size_t send_max = JERRY_DEBUGGER_SEND_MAX (uint8_t);
+ bool prev_is_object_bound = false;
+
+ uint8_t scope_types[send_max];
+
+ for (ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p;
+ lex_env_p != NULL;
+ lex_env_p = ecma_get_lex_env_outer_reference(lex_env_p))
+ {
+ if (ecma_is_lexical_environment (lex_env_p))
+ {
+ if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
+ {
+ if (count == 0 || prev_is_object_bound)
+ {
+ scope_types[count++] = JERRY_DEBUGGER_SCOPE_LOCAL;
+ }
+ else {
+ scope_types[count++] = JERRY_DEBUGGER_SCOPE_CLOSURE;
+ }
+
+ prev_is_object_bound = false;
+ }
+ else
+ {
+ JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+ if (ecma_get_lex_env_outer_reference(lex_env_p) == NULL)
+ {
+ scope_types[count++] = JERRY_DEBUGGER_SCOPE_GLOBAL;
+ }
+ else {
+ scope_types[count++] = JERRY_DEBUGGER_SCOPE_WITH;
+ prev_is_object_bound = true;
+ }
+ }
+ }
+ }
+
+ JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_type_p);
+
+ message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN;
+ memcpy (message_type_p->string, scope_types, count);
+
+ jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + count);
+
+} /* jerry_debugger_send_scope_chain */
+
+static jerry_debugger_scope_variable_type_t
+ecma_get_typeof_scope_variable (ecma_value_t value) /**< input ecma value */
+{
+ jerry_debugger_scope_variable_type_t ret_value = JERRY_DEBUGGER_VARIABLE_NONE;
+
+ if (ecma_is_value_undefined (value))
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_UNDEFINED;
+ }
+ else if (ecma_is_value_null (value))
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_OBJECT;
+ }
+ else if (ecma_is_value_boolean (value))
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_BOOLEAN;
+ }
+ else if (ecma_is_value_number (value))
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_NUMBER;
+ }
+ else if (ecma_is_value_string (value))
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_STRING;
+ }
+ else
+ {
+ JERRY_ASSERT (ecma_is_value_object (value));
+
+ if (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL)
+ {
+ ret_value = JERRY_DEBUGGER_VARIABLE_ARRAY;
+ }
+ else
+ {
+ ret_value = ecma_op_is_callable (value) ? JERRY_DEBUGGER_VARIABLE_FUNCTION : JERRY_DEBUGGER_VARIABLE_OBJECT;
+ }
+ }
+
+ JERRY_ASSERT (ret_value != JERRY_DEBUGGER_VARIABLE_NONE);
+
+ return ret_value;
+} /* ecma_get_typeof_scope_variable */
+
+static bool
+copy_value_to_string_message (jerry_debugger_scope_variable_type_t variable_type,
+ ecma_string_t *value_str,
+ jerry_debugger_send_string_t *message_string_p,
+ size_t *curr_msg_length)
+{
+ const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t);
+ const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t);
+
+ if (*curr_msg_length == max_byte_count)
+ {
+ if (!jerry_debugger_send (max_message_size))
+ {
+ return false;
+ }
+ }
+
+ if (variable_type != JERRY_DEBUGGER_VARIABLE_NONE)
+ {
+ uint8_t type_value = (uint8_t) variable_type;
+ memcpy (message_string_p->string + *curr_msg_length, &type_value, 1);
+ *curr_msg_length += 1;
+ }
+
+ ECMA_STRING_TO_UTF8_STRING (value_str, str_buff, str_buff_size);
+
+ if (*curr_msg_length == max_byte_count)
+ {
+ if (!jerry_debugger_send (max_message_size))
+ {
+ return false;
+ }
+ }
+
+ uint8_t str_size = (uint8_t) str_buff_size;
+ memcpy (message_string_p->string + *curr_msg_length, &str_size, 1);
+ *curr_msg_length += 1;
+
+ size_t free_bytes = max_byte_count - *curr_msg_length;
+ const uint8_t* string_p = str_buff;
+ size_t remained_size = str_buff_size;
+
+ while (remained_size > free_bytes)
+ {
+ memcpy (message_string_p->string + *curr_msg_length, string_p, free_bytes);
+
+ if (!jerry_debugger_send (max_message_size))
+ {
+ ECMA_FINALIZE_UTF8_STRING (str_buff, str_buff_size);
+
+ return false;
+ }
+
+ string_p += free_bytes;
+ remained_size -= free_bytes;
+ free_bytes = max_byte_count;
+ *curr_msg_length = 0;
+ }
+
+ memcpy (message_string_p->string + *curr_msg_length, string_p, remained_size);
+ *curr_msg_length += remained_size;
+
+ ECMA_FINALIZE_UTF8_STRING (str_buff, str_buff_size);
+
+ return true;
+} /* copy_value_to_string_message */
+
+static void
+jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p)
+{
+ JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_get_scope_variables_t, get_scope_variables_p);
+
+ uint32_t chain_index;
+ memcpy (&chain_index, get_scope_variables_p->chain_index, sizeof (uint32_t));
+
+ vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
+ ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p;
+
+ while (chain_index != 0)
+ {
+ lex_env_p = ecma_get_lex_env_outer_reference(lex_env_p);
+
+ if (lex_env_p == NULL)
+ {
+ jerry_debugger_send_type (JERRY_DEBUGGER_SCOPE_VARIABLES_END);
+ return;
+ }
+ chain_index--;
+ }
+
+ ecma_property_header_t* prop_iter_p;
+
+ if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) {
+ prop_iter_p = ecma_get_property_list (lex_env_p);
+ }
+ else {
+ JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+ ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
+ prop_iter_p = ecma_get_property_list (binding_obj_p);
+ }
+
+ JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p);
+
+ message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES;
+ size_t string_length = 0;
+
+ while (prop_iter_p != NULL)
+ {
+ JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
+
+ ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
+
+
+ for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
+ {
+ if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
+ {
+ ecma_string_t* prop_name = ecma_string_from_property_name (prop_iter_p->types[i],
+ prop_pair_p->names_cp[i]);
+
+ if (!copy_value_to_string_message (JERRY_DEBUGGER_VARIABLE_NONE,
+ prop_name,
+ message_string_p,
+ &string_length))
+ {
+ return;
+ }
+
+ ecma_property_value_t prop_value_p = prop_pair_p->values[i];
+ ecma_value_t final_str = ecma_op_to_string (prop_value_p.value);
+
+ if (!copy_value_to_string_message (ecma_get_typeof_scope_variable (prop_value_p.value),
+ ecma_get_string_from_value (final_str),
+ message_string_p,
+ &string_length))
+ {
+ return;
+ }
+
+ ecma_free_value (final_str);
+ }
+ }
+
+ prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
+ prop_iter_p->next_property_cp);
+ }
+
+ message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES_END;
+ jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + string_length);
+} /* jerry_debugger_send_scope_variables */
+
/**
* Send result of evaluated expression or throw an error.
*
@@ -525,6 +778,24 @@ jerry_debugger_process_message (const uint8_t *recv_buffer_p, /**< pointer to th
return true;
}
+ case JERRY_DEBUGGER_GET_SCOPE_CHAIN:
+ {
+ JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
+
+ jerry_debugger_send_scope_chain ();
+
+ return true;
+ }
+
+ case JERRY_DEBUGGER_GET_SCOPE_VARIABLES:
+ {
+ JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_get_scope_variables_t);
+
+ jerry_debugger_send_scope_variables (recv_buffer_p);
+
+ return true;
+ }
+
case JERRY_DEBUGGER_EXCEPTION_CONFIG:
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t);
diff --git a/jerry-core/debugger/debugger.h b/jerry-core/debugger/debugger.h
index 5b1db984..11caadcd 100644
--- a/jerry-core/debugger/debugger.h
+++ b/jerry-core/debugger/debugger.h
@@ -26,7 +26,7 @@
/**
* JerryScript debugger protocol version.
*/
-#define JERRY_DEBUGGER_VERSION (6)
+#define JERRY_DEBUGGER_VERSION (7)
/**
* Frequency of calling jerry_debugger_receive() by the VM.
@@ -157,7 +157,9 @@ typedef enum
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25, /**< engine waiting for source code */
JERRY_DEBUGGER_OUTPUT_RESULT = 26, /**< output sent by the program to the debugger */
JERRY_DEBUGGER_OUTPUT_RESULT_END = 27, /**< last output result data */
-
+ JERRY_DEBUGGER_SCOPE_CHAIN = 28,
+ JERRY_DEBUGGER_SCOPE_VARIABLES = 29,
+ JERRY_DEBUGGER_SCOPE_VARIABLES_END = 30,
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
/* Messages sent by the client to server. */
@@ -187,7 +189,8 @@ typedef enum
JERRY_DEBUGGER_GET_BACKTRACE = 16, /**< get backtrace */
JERRY_DEBUGGER_EVAL = 17, /**< first message of evaluating a string */
JERRY_DEBUGGER_EVAL_PART = 18, /**< next message of evaluating a string */
-
+ JERRY_DEBUGGER_GET_SCOPE_CHAIN = 19, /**< get the lex env names from the scope chain */
+ JERRY_DEBUGGER_GET_SCOPE_VARIABLES = 20,
JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT, /**< number of different type of input messages */
} jerry_debugger_header_type_t;
@@ -235,6 +238,33 @@ typedef enum
} jerry_debugger_output_subtype_t;
/**
+ * Types of scope chain.
+ *
+ */
+typedef enum
+{
+ JERRY_DEBUGGER_SCOPE_WITH = 1, /**< with */
+ JERRY_DEBUGGER_SCOPE_LOCAL = 2, /**< local */
+ JERRY_DEBUGGER_SCOPE_CLOSURE = 3, /**< closure */
+ JERRY_DEBUGGER_SCOPE_GLOBAL = 4, /**< global */
+ JERRY_DEBUGGER_SCOPE_CATCH = 5
+} jerry_debugger_scope_chain_type_t;
+
+
+typedef enum
+{
+ JERRY_DEBUGGER_VARIABLE_NONE = 1,
+ JERRY_DEBUGGER_VARIABLE_UNDEFINED = 2,
+ JERRY_DEBUGGER_VARIABLE_NULL = 3,
+ JERRY_DEBUGGER_VARIABLE_BOOLEAN = 4,
+ JERRY_DEBUGGER_VARIABLE_NUMBER = 5,
+ JERRY_DEBUGGER_VARIABLE_STRING = 6,
+ JERRY_DEBUGGER_VARIABLE_FUNCTION = 7,
+ JERRY_DEBUGGER_VARIABLE_ARRAY = 8,
+ JERRY_DEBUGGER_VARIABLE_OBJECT = 9
+} jerry_debugger_scope_variable_type_t;
+
+/**
* Byte data for evaluating expressions and receiving client source.
*/
typedef struct
@@ -370,6 +400,15 @@ typedef struct
} jerry_debugger_send_backtrace_t;
/**
+ * Outgoing message: scope chain information.
+ */
+typedef struct
+{
+ uint8_t type; /**< type of the message */
+ uint8_t chain_types[]; /**< scope chain types */
+} jerry_debugger_send_scope_chain_t;
+
+/**
* Outgoing message: number of total frames in backtrace.
*/
typedef struct
@@ -417,6 +456,15 @@ typedef struct
} jerry_debugger_receive_eval_first_t;
/**
+ * Incoming message: get scope variables
+*/
+typedef struct
+{
+ uint8_t type; /**< type of the message */
+ uint8_t chain_index[sizeof (uint32_t)]; /**< index element of the scope */
+} jerry_debugger_receive_get_scope_variables_t;
+
+/**
* Incoming message: first message of client source.
*/
typedef struct
diff --git a/jerry-debugger/jerry_client.py b/jerry-debugger/jerry_client.py
index 7e34b69c..e63dc770 100755
--- a/jerry-debugger/jerry_client.py
+++ b/jerry-debugger/jerry_client.py
@@ -118,6 +118,12 @@ class DebuggerPrompt(Cmd):
self.stop = True
do_bt = do_backtrace
+ def do_scope_variables(self, args):
+ """ Get scope variables from debugger """
+ write(self.debugger.scope_variables(args))
+ self.stop = True
+ do_sv = do_scope_variables
+
def do_src(self, args):
""" Get current source code """
if args:
@@ -172,6 +178,12 @@ class DebuggerPrompt(Cmd):
self.stop = True
do_ms = do_memstats
+ def do_scope_chain(self, _):
+ """ Memory statistics """
+ self.debugger.scope_chain()
+ self.stop = True
+ do_sc = do_scope_chain
+
def do_abort(self, args):
""" Throw an exception """
self.debugger.abort(args)
diff --git a/jerry-debugger/jerry_client_ws.py b/jerry-debugger/jerry_client_ws.py
index 246e3762..a26e6b97 100644
--- a/jerry-debugger/jerry_client_ws.py
+++ b/jerry-debugger/jerry_client_ws.py
@@ -22,9 +22,10 @@ import select
import socket
import struct
import sys
+from tabulate import tabulate
# Expected debugger protocol version.
-JERRY_DEBUGGER_VERSION = 6
+JERRY_DEBUGGER_VERSION = 7
# Messages sent by the server to client.
JERRY_DEBUGGER_CONFIGURATION = 1
@@ -54,6 +55,9 @@ JERRY_DEBUGGER_EVAL_RESULT_END = 24
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25
JERRY_DEBUGGER_OUTPUT_RESULT = 26
JERRY_DEBUGGER_OUTPUT_RESULT_END = 27
+JERRY_DEBUGGER_SCOPE_CHAIN = 28
+JERRY_DEBUGGER_SCOPE_VARIABLES = 29
+JERRY_DEBUGGER_SCOPE_VARIABLES_END = 30
# Debugger option flags
JERRY_DEBUGGER_LITTLE_ENDIAN = 0x1
@@ -94,11 +98,27 @@ JERRY_DEBUGGER_FINISH = 15
JERRY_DEBUGGER_GET_BACKTRACE = 16
JERRY_DEBUGGER_EVAL = 17
JERRY_DEBUGGER_EVAL_PART = 18
+JERRY_DEBUGGER_GET_SCOPE_CHAIN = 19
+JERRY_DEBUGGER_GET_SCOPE_VARIABLES = 20
MAX_BUFFER_SIZE = 128
WEBSOCKET_BINARY_FRAME = 2
WEBSOCKET_FIN_BIT = 0x80
+JERRY_DEBUGGER_SCOPE_WITH = 1
+JERRY_DEBUGGER_SCOPE_LOCAL = 2
+JERRY_DEBUGGER_SCOPE_CLOSURE = 3
+JERRY_DEBUGGER_SCOPE_GLOBAL = 4
+
+JERRY_DEBUGGER_VARIABLE_NONE = 1
+JERRY_DEBUGGER_VARIABLE_UNDEFINED = 2
+JERRY_DEBUGGER_VARIABLE_NULL = 3
+JERRY_DEBUGGER_VARIABLE_BOOLEAN = 4
+JERRY_DEBUGGER_VARIABLE_NUMBER = 5
+JERRY_DEBUGGER_VARIABLE_STRING = 6
+JERRY_DEBUGGER_VARIABLE_FUNCTION = 7
+JERRY_DEBUGGER_VARIABLE_ARRAY = 8
+JERRY_DEBUGGER_VARIABLE_OBJECT = 9
def arguments_parse():
parser = argparse.ArgumentParser(description="JerryScript debugger client")
@@ -264,6 +284,7 @@ class JerryDebugger(object):
self.source_name = ''
self.exception_string = ''
self.frame_index = 0
+ self.scope_vars = ""
self.client_sources = []
self.last_breakpoint_hit = None
self.next_breakpoint_index = 0
@@ -394,6 +415,10 @@ class JerryDebugger(object):
self.prompt = False
self._exec_command(JERRY_DEBUGGER_MEMSTATS)
+ def scope_chain(self):
+ self.prompt = False
+ self._exec_command(JERRY_DEBUGGER_GET_SCOPE_CHAIN)
+
def set_break(self, args):
if not args:
return "Error: Breakpoint index expected"
@@ -500,6 +525,27 @@ class JerryDebugger(object):
self.prompt = False
return ""
+ def scope_variables(self, args):
+ index = 0
+ if args:
+ try:
+ index = int(args)
+ if index < 0:
+ print ("Error: A non negative integer number expected")
+ return
+ except ValueError as val_errno:
+ return "Error: Non negative integer number expected, %s\n" % (vall_errno)
+
+ message = struct.pack(self.byte_order + "BBIB" + self.idx_format,
+ WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+ WEBSOCKET_FIN_BIT + 1 + 4,
+ 0,
+ JERRY_DEBUGGER_GET_SCOPE_VARIABLES,
+ index)
+ self.send_message(message)
+ self.prompt = False
+ return ""
+
def eval(self, code):
self._send_string(JERRY_DEBUGGER_EVAL_EVAL + code, JERRY_DEBUGGER_EVAL)
self.prompt = False
@@ -724,7 +770,6 @@ class JerryDebugger(object):
while True:
data = self.get_message(False)
-
if not self.non_interactive:
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
sys.stdin.readline()
@@ -848,7 +893,49 @@ class JerryDebugger(object):
elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE:
self.send_client_source()
+
+ elif buffer_type == JERRY_DEBUGGER_SCOPE_CHAIN:
+ scope_chain = []
+ for i in data[3:]:
+ if ord(i) == JERRY_DEBUGGER_SCOPE_WITH:
+ scope_chain.append("with")
+ elif ord(i) == JERRY_DEBUGGER_SCOPE_GLOBAL:
+ scope_chain.append("global")
+ elif ord(i) == JERRY_DEBUGGER_SCOPE_CLOSURE:
+ scope_chain.append("closure")
+ elif ord(i) == JERRY_DEBUGGER_SCOPE_LOCAL:
+ scope_chain.append("local")
+ else:
+ raise Exception("Unexpected scope chain element")
+
+ headers = ['index', 'type']
+ table = []
+ for index, scope_type in enumerate(scope_chain):
+ table.append([index, scope_type])
+
+ result = tabulate(table, headers = headers)
+ if not result.endswith('\n'):
+ result += '\n'
+
+ self.prompt = True
+
+ return DebuggerAction(DebuggerAction.TEXT, result)
+
+
+ elif buffer_type in [JERRY_DEBUGGER_SCOPE_VARIABLES, JERRY_DEBUGGER_SCOPE_VARIABLES_END]:
+ self.scope_vars += "".join(data[3:])
+
+ if buffer_type == JERRY_DEBUGGER_SCOPE_VARIABLES_END:
+ result = self.process_scope_variables()
+ self.scope_vars = ""
+
+ self.prompt = True
+
+ return DebuggerAction(DebuggerAction.TEXT, result)
+
+
else:
+ print (buffer_type)
raise Exception("Unknown message")
def print_source(self, line_num, offset):
@@ -1203,3 +1290,53 @@ class JerryDebugger(object):
if subtype == JERRY_DEBUGGER_EVAL_ERROR:
return "Uncaught exception: %s" % (message)
return message
+
+ def process_scope_variables(self):
+ buff_size = len(self.scope_vars)
+ buff_pos = 0
+
+ headers = ['name', 'type', 'value']
+ table = []
+
+ while buff_pos != buff_size:
+ # Process name
+ name_length = ord(self.scope_vars[buff_pos:buff_pos + 1])
+ buff_pos += 1
+ name = self.scope_vars[buff_pos:buff_pos + name_length]
+ buff_pos += name_length
+
+ # Process type
+ value_type = ord(self.scope_vars[buff_pos:buff_pos + 1])
+
+ buff_pos += 1
+
+ value_length = ord(self.scope_vars[buff_pos:buff_pos + 1])
+ buff_pos += 1
+ value = self.scope_vars[buff_pos: buff_pos + value_length]
+ buff_pos += value_length
+
+ if value_type == JERRY_DEBUGGER_VARIABLE_UNDEFINED:
+ table.append([name,'undefined'])
+ #result += 'undefined\n'
+ elif value_type == JERRY_DEBUGGER_VARIABLE_NULL:
+ table.append([name, 'Null'])
+ #result += 'Null\n'
+ elif value_type == JERRY_DEBUGGER_VARIABLE_BOOLEAN:
+ table.append([name,'Boolean', bool(value)])
+ elif value_type == JERRY_DEBUGGER_VARIABLE_NUMBER:
+ table.append([name,'Number', value])
+ elif value_type == JERRY_DEBUGGER_VARIABLE_STRING:
+ table.append([name,'String', value])
+ elif value_type == JERRY_DEBUGGER_VARIABLE_FUNCTION:
+ table.append([name,'Function', value])
+ elif value_type == JERRY_DEBUGGER_VARIABLE_ARRAY:
+ table.append([name,'Array', '[' + value + ']'])
+ elif value_type == JERRY_DEBUGGER_VARIABLE_OBJECT:
+ table.append([name,'Object', '{' + value + '}'])
+
+ result = tabulate(table, headers=headers)
+
+ if not result.endswith('\n'):
+ result += '\n'
+
+ return result
diff --git a/tools/apt-get-install-deps.sh b/tools/apt-get-install-deps.sh
index a2eaf6e9..8e791628 100755
--- a/tools/apt-get-install-deps.sh
+++ b/tools/apt-get-install-deps.sh
@@ -19,4 +19,4 @@ sudo apt-get install -q -y \
make cmake \
gcc gcc-multilib \
doxygen \
- cppcheck vera++ python
+ cppcheck vera++ python python-tabulate