Qore Programming Language 1.19.1
Loading...
Searching...
No Matches
QC_DebugProgram.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 QC_DebugProgram.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2023 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30*/
31
32#ifndef _QORE_CLASS_DEBUGPROGRAM_H
33
34#define _QORE_CLASS_DEBUGPROGRAM_H
35
36DLLEXPORT extern qore_classid_t CID_DEBUGPROGRAM;
37DLLLOCAL extern QoreClass* QC_DEBUGPROGRAM;
38DLLLOCAL QoreClass *initDebugProgramClass(QoreNamespace& ns);
39
40#include <qore/QoreDebugProgram.h>
41#include <qore/ReferenceArgumentHelper.h>
42
43// class needed to handle calls from C++ to Qore script instance
44class QoreDebugProgramWithQoreObject: public QoreDebugProgram {
45private:
46 QoreObject* qo;
47
48 DLLLOCAL void callMethod(const char* name, QoreProgram *pgm, int paramCount, QoreValue* params, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink, ExceptionSink &xsink2) {
49 ReferenceHolder<QoreListNode> args(new QoreListNode(autoTypeInfo), &xsink2);
50 args->push(QoreProgram::getQoreObject(pgm), nullptr);
51 for (int i=0; i<paramCount; i++) {
52 //printd(5, "QoreDebugProgramWithCoreObject::callMethod(%s) this: %p, param: %d/%d, type: %s\n", name, this, i, paramCount, params[i]?params[i]->getTypeName():"n/a");
53 args->push(params[i], nullptr);
54 }
55 // LocalVar will sanitize and discard non-node values so we cannot use the ReferenceHolder
56 ReferenceArgumentHelper rsah(rs, &xsink2);
57 args->push(rsah.getArg(), nullptr); // caller owns ref
58 int sid = rts ? pgm->getStatementId(rts) : 0;
59 ReferenceArgumentHelper rtsah(sid, &xsink2);
60 args->push(rtsah.getArg(), nullptr); // caller owns ref
61 printd(5, "QoreDebugProgramWithCoreObject::callMethod(%s) this: %p, pgm: %p, param#: %d, rs: %d, rts: %d, xsink2: %d\n", name, this, pgm, paramCount, rs, sid, xsink2.isEvent());
62 qo->evalMethod(name, *args, &xsink2);
63 QoreValue rsv(rsah.getOutputValue());
64 rs = (DebugRunStateEnum) rsv.getAsBigInt();
65 rsv.discard(&xsink2);
66
67 QoreValue rtsv(rtsah.getOutputValue());
68 sid = rtsv.getAsBigInt();
69 rtsv.discard(&xsink2);
70 if (sid <= 0) {
71 rts = nullptr;
72 } else {
73 rts = pgm->resolveStatementId(sid);
74 }
75
76 //printd(5, "QoreDebugProgramWithCoreObject::callMethod(%s) this: %p, pgm: %p, rs: %d\n", name, this, pgm, rs);
77 /* catch all exceptions from debug code, optionally we could assimilate on demand or create exception handler
78 * but developer can try/catch by himself to handle it
79 */
80 // xsink->assimilate(xsink2);
81 }
82
83public:
84 DLLLOCAL QoreDebugProgramWithQoreObject(QoreObject* n_qo): qo(n_qo) {
85 //printd(5, "QoreDebugProgramWithCoreObject::QoreDebugProgramWithCoreObject() this: %p, qo: %p\n", this, n_qo);
86 }
87 DLLLOCAL virtual void onAttach(QoreProgram *pgm, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
88 //printd(5, "QoreDebugProgramWithCoreObject::onAttach() this: %p, pgm: %p\n", this, pgm);
89 ExceptionSink xsink2;
90 callMethod("onAttach", pgm, 0, 0, rs, rts, xsink, xsink2);
91 }
92 DLLLOCAL virtual void onDetach(QoreProgram *pgm, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
93 printd(5, "QoreDebugProgramWithCoreObject::onDetach() this: %p, pgm: %p\n", this, pgm);
94 ExceptionSink xsink2;
95 callMethod("onDetach", pgm, 0, 0, rs, rts, xsink, xsink2);
96 }
97 DLLLOCAL virtual void onStep(QoreProgram *pgm, const StatementBlock *blockStatement, const AbstractStatement *statement, unsigned bkptId, int &flow, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
98 ExceptionSink xsink2;
99 QoreValue params[4];
100 params[0] = pgm->getStatementId(blockStatement);
101 params[1] = statement ? QoreValue(pgm->getStatementId(statement)) : QoreValue();
102 /*
103 if (!params[0]->getAsInt())
104 printd(5, "QoreDebugProgramWithCoreObject::onStep::blockStatement:%s:%d-%d:%s\n", blockStatement->loc.getFile(), blockStatement->loc.start_line, blockStatement->loc.end_line, typeid(blockStatement).name());
105 if (statement && !params[1]->getAsInt()) {
106 printd(5, "QoreDebugProgramWithCoreObject::onStep::statement:%s:%d-%d:%s\n", statement->loc.getFile(), statement->loc.start_line, statement->loc.end_line, typeid(statement).name());
107 }*/
108 params[2] = bkptId > 0 ? QoreValue(bkptId) : QoreValue();
109 // LocalVar will sanitize and discard non-node values so we cannot use the ReferenceHolder
110 ReferenceArgumentHelper rah(flow, &xsink2);
111 params[3] = rah.getArg(); // caller owns ref
112 callMethod("onStep", pgm, 4, params, rs, rts, xsink, xsink2);
113 QoreValue v(rah.getOutputValue());
114 flow = v.getAsBigInt();
115 v.discard(&xsink2);
116 }
117 DLLLOCAL virtual void onFunctionEnter(QoreProgram *pgm, const StatementBlock *blockStatement, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
118 ExceptionSink xsink2;
119 QoreValue params[1];
120 params[0] = pgm->getStatementId(blockStatement);
121 /*
122 if (!params[0]->getAsInt())
123 printd(5, "QoreDebugProgramWithCoreObject::onFunctionEnter::blockStatement:%s:%d-%d:%s\n", blockStatement->loc.getFile(), blockStatement->loc.start_line, blockStatement->loc.end_line, typeid(blockStatement).name());
124 */
125 callMethod("onFunctionEnter", pgm, 1, params, rs, rts, xsink, xsink2);
126 }
127 DLLLOCAL virtual void onFunctionExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
128 ExceptionSink xsink2;
129 QoreValue params[2];
130 params[0] = pgm->getStatementId(blockStatement);
131 /*
132 if (!params[0]->getAsInt())
133 printd(5, "QoreDebugProgramWithCoreObject::onFunctionExit::blockStatement:%s:%d-%d:%s\n", blockStatement->loc.getFile(), blockStatement->loc.start_line, blockStatement->loc.end_line, typeid(blockStatement).name());
134 */
135 //printd(5, "QoreDebugProgramWithCoreObject::onFunctionExit() getRetValue#0: type: %d, in: %p\n", returnValue.type, returnValue.getInternalNode());
136 ReferenceArgumentHelper rah(returnValue, &xsink2);
137 params[1] = rah.getArg(); // caller owns ref
138 callMethod("onFunctionExit", pgm, 2, params, rs, rts, xsink, xsink2);
139 returnValue = rah.getOutputValue(); // caller owns ref
140 //printd(5, "QoreDebugProgramWithCoreObject::onFunctionExit() getRetValue#3: type: %d, in: %p\n", returnValue.type, returnValue.getInternalNode());
141 }
142 DLLLOCAL virtual void onException(QoreProgram *pgm, const AbstractStatement *statement, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
143 ExceptionSink xsink2;
144 QoreValue params[3];
145 params[0] = pgm->getStatementId(statement);
146 /*
147 if (!params[0]->getAsInt())
148 printd(5, "QoreDebugProgramWithCoreObject::onException::statement:%s:%d-%d:%s\n", statement->loc.getFile(), statement->loc.start_line, statement->loc.end_line, typeid(statement).name());
149 */
150 QoreException* except = xsink->getException();
151 params[1] = except->makeExceptionObject();
152 // LocalVar will sanitize and discard non-node values so we cannot use the ReferenceHolder
153 ReferenceArgumentHelper rah(QoreValue(false), &xsink2);
154 params[2] = rah.getArg(); // caller owns ref
155 callMethod("onException", pgm, 3, params, rs, rts, xsink, xsink2);
156 QoreValue v(rah.getOutputValue());
157 if (v.getAsBool()) {
158 xsink->clear(); // dismiss exception
159 }
160 v.discard(&xsink2);
161 }
162 DLLLOCAL virtual void onExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, DebugRunStateEnum &rs, const AbstractStatement* &rts, ExceptionSink* xsink) {
163 ExceptionSink xsink2;
164 QoreValue params[2];
165 params[0] = pgm->getStatementId(blockStatement);
166 /*
167 if (!params[0]->getAsInt())
168 printd(5, "QoreDebugProgramWithCoreObject::onExit::blockStatement:%s:%d-%d:%s\n", blockStatement->loc.getFile(), blockStatement->loc.start_line, blockStatement->loc.end_line, typeid(blockStatement).name());
169 */
170 //printd(5, "QoreDebugProgramWithCoreObject::onExit() getRetValue#0: type: %d, in: %p\n", returnValue.type, returnValue.getInternalNode());
171 ReferenceArgumentHelper rah(returnValue, &xsink2);
172 params[1] = rah.getArg(); // caller owns ref
173 callMethod("onExit", pgm, 2, params, rs, rts, xsink, xsink2);
174 returnValue = rah.getOutputValue(); // caller owns ref
175 //printd(5, "QoreDebugProgramWithCoreObject::onExit() getRetValue#3: type: %d, in: %p\n", returnValue.type, returnValue.getInternalNode());
176 }
177};
178
179
180#endif // _QORE_CLASS_DEBUGPROGRAM_H
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT bool isEvent() const
returns true if at least one exception is present or thread_exit has been triggered
DLLEXPORT void clear()
deletes the exception list immediately
defines a Qore-language class
Definition: QoreClass.h:253
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreDebugProgram.h:66
virtual DLLEXPORT void onFunctionEnter(QoreProgram *pgm, const StatementBlock *statement, DebugRunStateEnum &rs, const AbstractStatement *&rts, ExceptionSink *xsink)
virtual DLLEXPORT void onStep(QoreProgram *pgm, const StatementBlock *blockStatement, const AbstractStatement *statement, unsigned bkptId, int &flow, DebugRunStateEnum &rs, const AbstractStatement *&rts, ExceptionSink *xsink)
virtual DLLEXPORT void onFunctionExit(QoreProgram *pgm, const StatementBlock *statement, QoreValue &returnValue, DebugRunStateEnum &rs, const AbstractStatement *&rts, ExceptionSink *xsink)
virtual DLLEXPORT void onExit(QoreProgram *pgm, const StatementBlock *statement, QoreValue &returnValue, DebugRunStateEnum &rs, const AbstractStatement *&rts, ExceptionSink *xsink)
virtual DLLEXPORT void onException(QoreProgram *pgm, const AbstractStatement *statement, DebugRunStateEnum &rs, const AbstractStatement *&rts, ExceptionSink *xsink)
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
contains constants, classes, and subnamespaces in QoreProgram objects
Definition: QoreNamespace.h:65
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition: QoreObject.h:60
DLLEXPORT QoreValue evalMethod(const QoreString *name, const QoreListNode *args, ExceptionSink *xsink)
evaluates the given method with the arguments passed and returns the return value,...
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
static DLLEXPORT QoreObject * getQoreObject(QoreProgram *pgm)
get QoreObject of QoreProgram
DLLEXPORT unsigned long getStatementId(const AbstractStatement *statement) const
get the statement id
DLLEXPORT AbstractStatement * resolveStatementId(unsigned long statementId) const
get the statement from statement id
allows a reference to be passed as an argument to Qore code
Definition: ReferenceArgumentHelper.h:58
a templated class to manage a reference count of an object that can throw a Qore-language exception w...
Definition: ReferenceHolder.h:52
unsigned qore_classid_t
used for the unique class ID for QoreClass objects
Definition: common.h:79
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276