Skip to content

Commit

Permalink
Support default class constructors in the debugger
Browse files Browse the repository at this point in the history
These functions have no source code and should be ignored by the debugger

Signed-off-by: Zoltan Herczeg [email protected]
  • Loading branch information
Zoltan Herczeg authored and clover2123 committed Sep 3, 2021
1 parent 81bae46 commit ed55d51
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 13 deletions.
12 changes: 12 additions & 0 deletions src/debugger/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,16 @@ class Debugger : public gc {
return m_enabled;
}

bool parsingEnabled()
{
return m_parsingEnabled;
}

void setParsingEnabled(bool value)
{
m_parsingEnabled = value;
}

bool pendingWait(void)
{
return m_pendingWait;
Expand Down Expand Up @@ -216,6 +226,7 @@ class Debugger : public gc {
protected:
Debugger()
: m_enabled(false)
, m_parsingEnabled(false)
, m_debuggerEnabled(nullptr)
, m_delay(ESCARGOT_DEBUGGER_MESSAGE_PROCESS_DELAY)
, m_pendingWait(false)
Expand All @@ -232,6 +243,7 @@ class Debugger : public gc {
virtual void close(void) = 0;

bool m_enabled;
bool m_parsingEnabled;
bool* m_debuggerEnabled;

private:
Expand Down
1 change: 1 addition & 0 deletions src/debugger/DebuggerTcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ bool DebuggerTcp::init(const char*)
}

m_enabled = true;
m_parsingEnabled = true;
m_receiveBufferFill = 0;
m_messageLength = 0;
return true;
Expand Down
12 changes: 7 additions & 5 deletions src/interpreter/ByteCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,10 @@ void ByteCodeGenerateContext::insertBreakpoint(size_t index, Node* node)

void ByteCodeGenerateContext::insertBreakpointAt(size_t line, Node* node)
{
m_breakpointContext->m_breakpointLocations.push_back(Debugger::BreakpointLocation(line, (uint32_t)m_byteCodeBlock->currentCodeSize()));
m_byteCodeBlock->pushCode(BreakpointDisabled(ByteCodeLOC(node->loc().index)), this, node);
if (m_breakpointContext->m_parsingEnabled) {
m_breakpointContext->m_breakpointLocations.push_back(Debugger::BreakpointLocation(line, (uint32_t)m_byteCodeBlock->currentCodeSize()));
m_byteCodeBlock->pushCode(BreakpointDisabled(ByteCodeLOC(node->loc().index)), this, node);
}
}

#endif /* ESCARGOT_DEBUGGER */
Expand Down Expand Up @@ -183,7 +185,7 @@ ByteCodeBlock* ByteCodeGenerator::generateByteCode(Context* context, Interpreted
ByteCodeGenerateContext ctx(codeBlock, block, codeBlock->isGlobalScope(), codeBlock->isEvalCode(), inWithFromRuntime || codeBlock->inWith(), nData);

#ifdef ESCARGOT_DEBUGGER
ByteCodeBreakpointContext breakpointContext;
ByteCodeBreakpointContext breakpointContext(context->debugger() && context->debugger()->parsingEnabled());
ctx.m_breakpointContext = &breakpointContext;
#endif /* ESCARGOT_DEBUGGER */

Expand All @@ -210,7 +212,7 @@ ByteCodeBlock* ByteCodeGenerator::generateByteCode(Context* context, Interpreted
ast->generateStatementByteCode(block, &ctx);

#ifdef ESCARGOT_DEBUGGER
if (context->debugger() && context->debugger()->enabled()) {
if (context->debugger() && context->debugger()->enabled() && breakpointContext.m_parsingEnabled) {
context->debugger()->sendBreakpointLocations(breakpointContext.m_breakpointLocations);
}
#endif /* ESCARGOT_DEBUGGER */
Expand Down Expand Up @@ -279,7 +281,7 @@ void ByteCodeGenerator::collectByteCodeLOCData(Context* context, InterpretedCode
ctx.m_locData = locData;

#ifdef ESCARGOT_DEBUGGER
ByteCodeBreakpointContext breakpointContext;
ByteCodeBreakpointContext breakpointContext(context->debugger()->parsingEnabled());
ctx.m_breakpointContext = &breakpointContext;
#endif /* ESCARGOT_DEBUGGER */

Expand Down
6 changes: 4 additions & 2 deletions src/interpreter/ByteCodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ struct ClassContextInformation {

#ifdef ESCARGOT_DEBUGGER
struct ByteCodeBreakpointContext {
bool m_parsingEnabled;
size_t m_lastBreakpointLineOffset;
size_t m_lastBreakpointIndexOffset;
std::vector<Debugger::BreakpointLocation> m_breakpointLocations;

ByteCodeBreakpointContext()
: m_lastBreakpointLineOffset(0)
ByteCodeBreakpointContext(bool parsingEnabled)
: m_parsingEnabled(parsingEnabled)
, m_lastBreakpointLineOffset(0)
, m_lastBreakpointIndexOffset(0)
{
}
Expand Down
13 changes: 12 additions & 1 deletion src/parser/ScriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,12 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(String* sour
void ScriptParser::generateFunctionByteCode(ExecutionState& state, InterpretedCodeBlock* codeBlock, size_t stackSizeRemain)
{
#ifdef ESCARGOT_DEBUGGER
ASSERT(m_context->debugger() == nullptr || !m_context->debugger()->enabled());
// When the debugger is enabled, lazy compilation is disabled, so the functions are compiled
// during parsing, and this function is never called. However, implicit class constructors
// has no source code, and still compiled later. These functions are ignored by the debugger.
if (m_context->debugger() != nullptr) {
m_context->debugger()->setParsingEnabled(false);
}
#endif /* ESCARGOT_DEBUGGER */

GC_disable();
Expand All @@ -530,6 +535,12 @@ void ScriptParser::generateFunctionByteCode(ExecutionState& state, InterpretedCo
// reset ASTAllocator
m_context->astAllocator().reset();
GC_enable();

#ifdef ESCARGOT_DEBUGGER
if (m_context->debugger() != nullptr) {
m_context->debugger()->setParsingEnabled(true);
}
#endif /* ESCARGOT_DEBUGGER */
}

#ifdef ESCARGOT_DEBUGGER
Expand Down
2 changes: 1 addition & 1 deletion src/parser/ast/ReturnStatementNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ReturnStatementNode : public StatementNode {
virtual void generateStatementByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context) override
{
#ifdef ESCARGOT_DEBUGGER
if (context->m_breakpointContext->m_breakpointLocations.size() == 0) {
if (context->m_breakpointContext->m_breakpointLocations.size() == 0 && context->m_breakpointContext->m_parsingEnabled) {
ASSERT(context->m_breakpointContext->m_lastBreakpointLineOffset == 0);
ASSERT(context->m_breakpointContext->m_breakpointLocations.size() == 0);

Expand Down
11 changes: 7 additions & 4 deletions tools/debugger/debugger_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,10 +443,13 @@ def process_messages(self):
elif buffer_type in [ESCARGOT_MESSAGE_BACKTRACE,
ESCARGOT_MESSAGE_EXCEPTION_BACKTRACE]:
backtrace_info = struct.unpack(self.byte_order + self.pointer_format + self.idx_format + self.idx_format + self.idx_format, data[1:])
function = self.function_list[backtrace_info[0]]
result = "%s:%d:%d [depth:%d]" % (function.source_name, backtrace_info[1], backtrace_info[2],backtrace_info[3])
if function.name != "":
result += " (in %s)" % (function.name)
function = self.function_list.get(backtrace_info[0])
if function is not None:
result = "%s:%d:%d [depth:%d]" % (function.source_name, backtrace_info[1], backtrace_info[2], backtrace_info[3])
if function.name != "":
result += " (in %s)" % (function.name)
else:
result = "unknown dynamic function:%d:%d [depth:%d]" % (backtrace_info[1], backtrace_info[2], backtrace_info[3])

if buffer_type == ESCARGOT_MESSAGE_BACKTRACE:
return DebuggerAction(DebuggerAction.TEXT, result + "\n")
Expand Down
22 changes: 22 additions & 0 deletions tools/debugger/tests/do_step_class2.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
s
bt
s
s
s
s
bt
s
s
s
s
s
bt
s
s
s
s
bt
s
s
s
s
53 changes: 53 additions & 0 deletions tools/debugger/tests/do_step_class2.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Connecting to: localhost:6501
Connection created!!!
Stopped at tools/debugger/tests/do_step_class2.js:20
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:32 (in function() at line:33, col:7)
(escargot-debugger) bt
tools/debugger/tests/do_step_class2.js:33:6 [depth:0]
tools/debugger/tests/do_step_class2.js:22:14 [depth:1]
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:36 (in function() at line:38, col:7)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:39 (in function() at line:39, col:23)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:39 (in function() at line:39, col:46)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:50 (in function() at line:51, col:7)
(escargot-debugger) bt
tools/debugger/tests/do_step_class2.js:51:6 [depth:0]
tools/debugger/tests/do_step_class2.js:42:29 [depth:1]
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:54 (in function() at line:55, col:7)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:56 (in function() at line:56, col:24)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:56 (in function() at line:56, col:48)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:59
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:23 (in function() at line:24, col:7)
(escargot-debugger) bt
tools/debugger/tests/do_step_class2.js:24:6 [depth:0]
unknown dynamic function:3:7 [depth:2]
tools/debugger/tests/do_step_class2.js:59:9 [depth:3]
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:26 (in function() at line:28, col:7)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:29 (in function() at line:29, col:15)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:29 (in function() at line:29, col:30)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:43 (in function() at line:44, col:7)
(escargot-debugger) bt
tools/debugger/tests/do_step_class2.js:44:6 [depth:0]
unknown dynamic function:3:7 [depth:1]
tools/debugger/tests/do_step_class2.js:59:9 [depth:2]
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:46 (in function() at line:46, col:16)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:47 (in function() at line:47, col:16)
(escargot-debugger) s
Stopped at tools/debugger/tests/do_step_class2.js:47 (in function() at line:47, col:31)
(escargot-debugger) s
Connection closed.
59 changes: 59 additions & 0 deletions tools/debugger/tests/do_step_class2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2021-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/

var o = null

class Class1 {
c1_field1
= 1
c1_field2
[
"c1_field3"
] = 2
c1_field4 = 3; c1_field5 = 4

static
c1_sfield1
= 1
static c1_sfield2
static
[
"c1_sfield3"
] = 2
static c1_sfield4 = 3; static c1_sfield5 = 4
}

class Class2 extends Class1 {
#c2_field1
= 1
#c2_field2
#c2_field3 = 2
#c2_field4 = 3; c2_field5 = 4

static
#c2_sfield1
= 1
static #c2_sfield2
static
#c2_sfield3
= 2
static #c2_sfield4 = 3; static #c1_sfield5 = 4
}

o = new Class2

0 comments on commit ed55d51

Please sign in to comment.