Support default class constructors in the debugger

These functions have no source code and should be ignored by the debugger

Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2021-08-31 06:32:57 +00:00 committed by Hyukwoo Park
commit ed55d51384
10 changed files with 178 additions and 13 deletions

View file

@ -173,6 +173,16 @@ public:
return m_enabled;
}
bool parsingEnabled()
{
return m_parsingEnabled;
}
void setParsingEnabled(bool value)
{
m_parsingEnabled = value;
}
bool pendingWait(void)
{
return m_pendingWait;
@ -216,6 +226,7 @@ public:
protected:
Debugger()
: m_enabled(false)
, m_parsingEnabled(false)
, m_debuggerEnabled(nullptr)
, m_delay(ESCARGOT_DEBUGGER_MESSAGE_PROCESS_DELAY)
, m_pendingWait(false)
@ -232,6 +243,7 @@ protected:
virtual void close(void) = 0;
bool m_enabled;
bool m_parsingEnabled;
bool* m_debuggerEnabled;
private:

View file

@ -372,6 +372,7 @@ bool DebuggerTcp::init(const char*)
}
m_enabled = true;
m_parsingEnabled = true;
m_receiveBufferFill = 0;
m_messageLength = 0;
return true;

View file

@ -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 */
@ -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 */
@ -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 */
@ -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 */

View file

@ -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)
{
}

View file

@ -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();
@ -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

View file

@ -36,7 +36,7 @@ public:
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);

View file

@ -443,10 +443,13 @@ class Debugger(object):
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")

View file

@ -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

View file

@ -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.

View file

@ -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