diff options
author | Robert Sipka <rsipka.uszeged@partner.samsung.com> | 2018-10-02 16:18:05 +0200 |
---|---|---|
committer | Robert Sipka <rsipka.uszeged@partner.samsung.com> | 2018-10-02 16:18:05 +0200 |
commit | 008bddc20346ba86bcdbb6bfe7865e3d19269e83 (patch) | |
tree | 40b2de3dc1b167c16504f24e3c8e0afda6df7fd8 | |
parent | 7717d2ee27723b9452d98f4b5082e03ca685cf85 (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.c | 277 | ||||
-rw-r--r-- | jerry-core/debugger/debugger.h | 54 | ||||
-rwxr-xr-x | jerry-debugger/jerry_client.py | 12 | ||||
-rw-r--r-- | jerry-debugger/jerry_client_ws.py | 141 | ||||
-rwxr-xr-x | tools/apt-get-install-deps.sh | 2 |
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 |