From 25f1718d848e71c33bddccc71209d5ad20c7aa13 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Tue, 28 Aug 2018 23:56:57 +0200 Subject: [PATCH] Move some internal functions into JerryDebugger. (#2484) JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-debugger/jerry_client_ws.py | 442 +++++++++++++++--------------- 1 file changed, 221 insertions(+), 221 deletions(-) diff --git a/jerry-debugger/jerry_client_ws.py b/jerry-debugger/jerry_client_ws.py index 3d2aaaf20..4e3bf170d 100644 --- a/jerry-debugger/jerry_client_ws.py +++ b/jerry-debugger/jerry_client_ws.py @@ -25,7 +25,6 @@ import sys # Expected debugger protocol version. JERRY_DEBUGGER_VERSION = 5 -JERRY_DEBUGGER_DATA_END = '\3' # Messages sent by the server to client. JERRY_DEBUGGER_CONFIGURATION = 1 @@ -400,12 +399,12 @@ class JerryDebugger(object): if int(args.split(':', 1)[1]) <= 0: return "Error: Positive breakpoint index expected" - return _set_breakpoint(self, args, False) + return self._set_breakpoint(args, False) except ValueError as val_errno: return "Error: Positive breakpoint index expected: %s" % (val_errno) - return _set_breakpoint(self, args, False) + return self._set_breakpoint(args, False) def delete(self, args): if not args: @@ -749,7 +748,7 @@ class JerryDebugger(object): JERRY_DEBUGGER_SOURCE_CODE_NAME_END, JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: - result = _parse_source(self, data) + result = self._parse_source(data) if result: return DebuggerAction(DebuggerAction.TEXT, result) @@ -757,12 +756,12 @@ class JerryDebugger(object): self.send_command(JERRY_DEBUGGER_PARSER_RESUME) elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP: - _release_function(self, data) + self._release_function(data) elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_HIT, JERRY_DEBUGGER_EXCEPTION_HIT]: breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format, data[3:]) - breakpoint = _get_breakpoint(self, breakpoint_data) + breakpoint = self._get_breakpoint(breakpoint_data) self.last_breakpoint_hit = breakpoint[0] if buffer_type == JERRY_DEBUGGER_EXCEPTION_HIT: @@ -806,7 +805,7 @@ class JerryDebugger(object): breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format, data[buffer_pos: buffer_pos + self.cp_size + 4]) - breakpoint = _get_breakpoint(self, breakpoint_data) + breakpoint = self._get_breakpoint(breakpoint_data) result += "Frame %d: %s\n" % (frame_index, breakpoint[0]) @@ -926,253 +925,254 @@ class JerryDebugger(object): return msg -# pylint: disable=too-many-branches,too-many-locals,too-many-statements -def _parse_source(debugger, data): - source_code = "" - source_code_name = "" - function_name = "" - stack = [{"line": 1, - "column": 1, - "name": "", - "lines": [], - "offsets": []}] - new_function_list = {} + # pylint: disable=too-many-branches,too-many-locals,too-many-statements + def _parse_source(self, data): + source_code = "" + source_code_name = "" + function_name = "" + stack = [{"line": 1, + "column": 1, + "name": "", + "lines": [], + "offsets": []}] + new_function_list = {} - while True: - if data is None: - return "Error: connection lost during source code receiving" + while True: + if data is None: + return "Error: connection lost during source code receiving" - buffer_type = ord(data[2]) - buffer_size = ord(data[1]) - 1 + buffer_type = ord(data[2]) + buffer_size = ord(data[1]) - 1 - logging.debug("Parser buffer type: %d, message size: %d", buffer_type, buffer_size) + logging.debug("Parser buffer type: %d, message size: %d", buffer_type, buffer_size) - if buffer_type == JERRY_DEBUGGER_PARSE_ERROR: - logging.error("Syntax error found") - return "" + if buffer_type == JERRY_DEBUGGER_PARSE_ERROR: + logging.error("Syntax error found") + return "" - elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]: - source_code += data[3:] + elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]: + source_code += data[3:] - elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE_NAME, JERRY_DEBUGGER_SOURCE_CODE_NAME_END]: - source_code_name += data[3:] + elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE_NAME, JERRY_DEBUGGER_SOURCE_CODE_NAME_END]: + source_code_name += data[3:] - elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: - function_name += data[3:] + elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: + function_name += data[3:] - elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION: - logging.debug("Source name: %s, function name: %s", source_code_name, function_name) + elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION: + logging.debug("Source name: %s, function name: %s", source_code_name, function_name) - position = struct.unpack(debugger.byte_order + debugger.idx_format + debugger.idx_format, - data[3: 3 + 4 + 4]) + position = struct.unpack(self.byte_order + self.idx_format + self.idx_format, + data[3: 3 + 4 + 4]) - stack.append({"source": source_code, - "source_name": source_code_name, - "line": position[0], - "column": position[1], - "name": function_name, - "lines": [], - "offsets": []}) - function_name = "" + stack.append({"source": source_code, + "source_name": source_code_name, + "line": position[0], + "column": position[1], + "name": function_name, + "lines": [], + "offsets": []}) + function_name = "" - elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]: - name = "lines" - if buffer_type == JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST: - name = "offsets" + elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]: + name = "lines" + if buffer_type == JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST: + name = "offsets" - logging.debug("Breakpoint %s received", name) + logging.debug("Breakpoint %s received", name) - buffer_pos = 3 - while buffer_size > 0: - line = struct.unpack(debugger.byte_order + debugger.idx_format, - data[buffer_pos: buffer_pos + 4]) - stack[-1][name].append(line[0]) - buffer_pos += 4 - buffer_size -= 4 + buffer_pos = 3 + while buffer_size > 0: + line = struct.unpack(self.byte_order + self.idx_format, + data[buffer_pos: buffer_pos + 4]) + stack[-1][name].append(line[0]) + buffer_pos += 4 + buffer_size -= 4 - elif buffer_type == JERRY_DEBUGGER_BYTE_CODE_CP: - byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format, - data[3: 3 + debugger.cp_size])[0] + elif buffer_type == JERRY_DEBUGGER_BYTE_CODE_CP: + byte_code_cp = struct.unpack(self.byte_order + self.cp_format, + data[3: 3 + self.cp_size])[0] - logging.debug("Byte code cptr received: {0x%x}", byte_code_cp) + logging.debug("Byte code cptr received: {0x%x}", byte_code_cp) - func_desc = stack.pop() + func_desc = stack.pop() - # We know the last item in the list is the general byte code. - if not stack: - func_desc["source"] = source_code - func_desc["source_name"] = source_code_name + # We know the last item in the list is the general byte code. + if not stack: + func_desc["source"] = source_code + func_desc["source_name"] = source_code_name - function = JerryFunction(stack, - byte_code_cp, - func_desc["source"], - func_desc["source_name"], - func_desc["line"], - func_desc["column"], - func_desc["name"], - func_desc["lines"], - func_desc["offsets"]) + function = JerryFunction(stack, + byte_code_cp, + func_desc["source"], + func_desc["source_name"], + func_desc["line"], + func_desc["column"], + func_desc["name"], + func_desc["lines"], + func_desc["offsets"]) - new_function_list[byte_code_cp] = function + new_function_list[byte_code_cp] = function - if not stack: - logging.debug("Parse completed.") - break - - elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP: - # Redefined functions are dropped during parsing. - byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format, - data[3: 3 + debugger.cp_size])[0] - - if byte_code_cp in new_function_list: - del new_function_list[byte_code_cp] - debugger.send_bytecode_cp(byte_code_cp) - else: - _release_function(debugger, data) - - else: - logging.error("Parser error!") - raise Exception("Unexpected message") - - data = debugger.get_message(True) - - # Copy the ready list to the global storage. - debugger.function_list.update(new_function_list) - - for function in new_function_list.values(): - for line, breakpoint in function.lines.items(): - debugger.line_list.insert(line, breakpoint) - - # Try to set the pending breakpoints - if debugger.pending_breakpoint_list: - result = "" - logging.debug("Pending breakpoints list: %s", debugger.pending_breakpoint_list) - bp_list = debugger.pending_breakpoint_list - - for breakpoint_index, breakpoint in bp_list.items(): - source_lines = 0 - for src in new_function_list.values(): - if src.source_name == breakpoint.source_name: - source_lines = len(src.source) + if not stack: + logging.debug("Parse completed.") break - if breakpoint.line: - if breakpoint.line <= source_lines: - command = breakpoint.source_name + ":" + str(breakpoint.line) - set_result = _set_breakpoint(debugger, command, True) + elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP: + # Redefined functions are dropped during parsing. + byte_code_cp = struct.unpack(self.byte_order + self.cp_format, + data[3: 3 + self.cp_size])[0] + + if byte_code_cp in new_function_list: + del new_function_list[byte_code_cp] + self.send_bytecode_cp(byte_code_cp) + else: + self._release_function(data) + + else: + logging.error("Parser error!") + raise Exception("Unexpected message") + + data = self.get_message(True) + + # Copy the ready list to the global storage. + self.function_list.update(new_function_list) + + for function in new_function_list.values(): + for line, breakpoint in function.lines.items(): + self.line_list.insert(line, breakpoint) + + # Try to set the pending breakpoints + if self.pending_breakpoint_list: + result = "" + logging.debug("Pending breakpoints list: %s", self.pending_breakpoint_list) + bp_list = self.pending_breakpoint_list + + for breakpoint_index, breakpoint in bp_list.items(): + source_lines = 0 + for src in new_function_list.values(): + if src.source_name == breakpoint.source_name: + source_lines = len(src.source) + break + + if breakpoint.line: + if breakpoint.line <= source_lines: + command = breakpoint.source_name + ":" + str(breakpoint.line) + set_result = self._set_breakpoint(command, True) + + if set_result: + result += set_result + del bp_list[breakpoint_index] + elif breakpoint.function: + command = breakpoint.function + set_result = self._set_breakpoint(command, True) if set_result: result += set_result del bp_list[breakpoint_index] - elif breakpoint.function: - command = breakpoint.function - set_result = _set_breakpoint(debugger, command, True) - if set_result: - result += set_result - del bp_list[breakpoint_index] + if not bp_list: + self.send_parser_config(0) + return result + + logging.debug("No pending breakpoints") + return "" + + + def _release_function(self, data): + byte_code_cp = struct.unpack(self.byte_order + self.cp_format, + data[3: 3 + self.cp_size])[0] + + function = self.function_list[byte_code_cp] + + for line, breakpoint in function.lines.items(): + self.line_list.delete(line, breakpoint) + if breakpoint.active_index >= 0: + del self.active_breakpoint_list[breakpoint.active_index] + + del self.function_list[byte_code_cp] + self.send_bytecode_cp(byte_code_cp) + logging.debug("Function {0x%x} byte-code released", byte_code_cp) + + + def _enable_breakpoint(self, breakpoint): + if isinstance(breakpoint, JerryPendingBreakpoint): + if self.breakpoint_pending_exists(breakpoint): + return "%sPending breakpoint%s already exists\n" % (self.yellow, self.nocolor) + + self.next_breakpoint_index += 1 + breakpoint.index = self.next_breakpoint_index + self.pending_breakpoint_list[self.next_breakpoint_index] = breakpoint + return ("%sPending breakpoint %d%s at %s\n" % (self.yellow, + breakpoint.index, + self.nocolor, + breakpoint)) + + if breakpoint.active_index < 0: + self.next_breakpoint_index += 1 + self.active_breakpoint_list[self.next_breakpoint_index] = breakpoint + breakpoint.active_index = self.next_breakpoint_index + self.send_breakpoint(breakpoint) + + return "%sBreakpoint %d%s at %s\n" % (self.green, + breakpoint.active_index, + self.nocolor, + breakpoint) + + + def _set_breakpoint(self, string, pending): + line = re.match("(.*):(\\d+)$", string) + result = "" + + if line: + source_name = line.group(1) + new_line = int(line.group(2)) + + for breakpoint in self.line_list.get(new_line): + func_source = breakpoint.function.source_name + if (source_name == func_source or + func_source.endswith("/" + source_name) or + func_source.endswith("\\" + source_name)): + + result += self._enable_breakpoint(breakpoint) + + else: + for function in self.function_list.values(): + if function.name == string: + result += self._enable_breakpoint(function.lines[function.first_breakpoint_line]) + + if not result and not pending: + print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \ + (self.yellow, self.nocolor)) + + ans = sys.stdin.readline() + if ans in ['yes\n', 'y\n']: + if not self.pending_breakpoint_list: + self.send_parser_config(1) + + if line: + breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1)) + else: + breakpoint = JerryPendingBreakpoint(function=string) + result += self._enable_breakpoint(breakpoint) - if not bp_list: - debugger.send_parser_config(0) return result - logging.debug("No pending breakpoints") - return "" + def _get_breakpoint(self, breakpoint_data): + function = self.function_list[breakpoint_data[0]] + offset = breakpoint_data[1] -def _release_function(debugger, data): - byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format, - data[3: 3 + debugger.cp_size])[0] + if offset in function.offsets: + return (function.offsets[offset], True) - function = debugger.function_list[byte_code_cp] + if offset < function.first_breakpoint_offset: + return (function.offsets[function.first_breakpoint_offset], False) - for line, breakpoint in function.lines.items(): - debugger.line_list.delete(line, breakpoint) - if breakpoint.active_index >= 0: - del debugger.active_breakpoint_list[breakpoint.active_index] + nearest_offset = -1 - del debugger.function_list[byte_code_cp] - debugger.send_bytecode_cp(byte_code_cp) - logging.debug("Function {0x%x} byte-code released", byte_code_cp) + for current_offset in function.offsets: + if current_offset <= offset and current_offset > nearest_offset: + nearest_offset = current_offset - -def _enable_breakpoint(debugger, breakpoint): - if isinstance(breakpoint, JerryPendingBreakpoint): - if debugger.breakpoint_pending_exists(breakpoint): - return "%sPending breakpoint%s already exists\n" % (debugger.yellow, debugger.nocolor) - - debugger.next_breakpoint_index += 1 - breakpoint.index = debugger.next_breakpoint_index - debugger.pending_breakpoint_list[debugger.next_breakpoint_index] = breakpoint - return ("%sPending breakpoint %d%s at %s\n" % (debugger.yellow, - breakpoint.index, - debugger.nocolor, - breakpoint)) - if breakpoint.active_index < 0: - debugger.next_breakpoint_index += 1 - debugger.active_breakpoint_list[debugger.next_breakpoint_index] = breakpoint - breakpoint.active_index = debugger.next_breakpoint_index - debugger.send_breakpoint(breakpoint) - - return "%sBreakpoint %d%s at %s\n" % (debugger.green, - breakpoint.active_index, - debugger.nocolor, - breakpoint) - - -def _set_breakpoint(debugger, string, pending): - line = re.match("(.*):(\\d+)$", string) - result = "" - - if line: - source_name = line.group(1) - new_line = int(line.group(2)) - - for breakpoint in debugger.line_list.get(new_line): - func_source = breakpoint.function.source_name - if (source_name == func_source or - func_source.endswith("/" + source_name) or - func_source.endswith("\\" + source_name)): - - result += _enable_breakpoint(debugger, breakpoint) - - else: - for function in debugger.function_list.values(): - if function.name == string: - result += _enable_breakpoint(debugger, function.lines[function.first_breakpoint_line]) - - if not result and not pending: - print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \ - (debugger.yellow, debugger.nocolor)) - - ans = sys.stdin.readline() - if ans in ['yes\n', 'y\n']: - if not debugger.pending_breakpoint_list: - debugger.send_parser_config(1) - - if line: - breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1)) - else: - breakpoint = JerryPendingBreakpoint(function=string) - result += _enable_breakpoint(debugger, breakpoint) - - return result - - -def _get_breakpoint(debugger, breakpoint_data): - function = debugger.function_list[breakpoint_data[0]] - offset = breakpoint_data[1] - - if offset in function.offsets: - return (function.offsets[offset], True) - - if offset < function.first_breakpoint_offset: - return (function.offsets[function.first_breakpoint_offset], False) - - nearest_offset = -1 - - for current_offset in function.offsets: - if current_offset <= offset and current_offset > nearest_offset: - nearest_offset = current_offset - - return (function.offsets[nearest_offset], False) + return (function.offsets[nearest_offset], False)