forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathduk_api_debug.c
167 lines (142 loc) · 5.18 KB
/
duk_api_debug.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
* Debugging related API calls
*/
#include "duk_internal.h"
DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) {
duk_idx_t idx;
duk_idx_t top;
DUK_ASSERT_CTX_VALID(ctx);
/* We don't duk_require_stack() here now, but rely on the caller having
* enough space.
*/
top = duk_get_top(ctx);
duk_push_array(ctx);
for (idx = 0; idx < top; idx++) {
duk_dup(ctx, idx);
duk_put_prop_index(ctx, -2, idx);
}
/* XXX: conversion errors should not propagate outwards.
* Perhaps values need to be coerced individually?
*/
duk_bi_json_stringify_helper(ctx,
duk_get_top_index(ctx), /*idx_value*/
DUK_INVALID_INDEX, /*idx_replacer*/
DUK_INVALID_INDEX, /*idx_space*/
DUK_JSON_FLAG_EXT_CUSTOM |
DUK_JSON_FLAG_ASCII_ONLY |
DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);
duk_push_sprintf(ctx, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(ctx, -1));
duk_replace(ctx, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */
duk_pop(ctx);
DUK_ASSERT(duk_is_string(ctx, -1));
}
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
duk_debug_read_function read_cb,
duk_debug_write_function write_cb,
duk_debug_peek_function peek_cb,
duk_debug_read_flush_function read_flush_cb,
duk_debug_write_flush_function write_flush_cb,
duk_debug_detached_function detached_cb,
void *udata) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_heap *heap;
const char *str;
duk_size_t len;
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(read_cb != NULL);
DUK_ASSERT(write_cb != NULL);
/* Other callbacks are optional. */
heap = thr->heap;
heap->dbg_read_cb = read_cb;
heap->dbg_write_cb = write_cb;
heap->dbg_peek_cb = peek_cb;
heap->dbg_read_flush_cb = read_flush_cb;
heap->dbg_write_flush_cb = write_flush_cb;
heap->dbg_detached_cb = detached_cb;
heap->dbg_udata = udata;
/* Start in paused state. */
heap->dbg_processing = 0;
heap->dbg_paused = 1;
heap->dbg_state_dirty = 1;
heap->dbg_step_type = 0;
heap->dbg_step_thread = NULL;
heap->dbg_step_csindex = 0;
heap->dbg_step_startline = 0;
heap->dbg_exec_counter = 0;
heap->dbg_last_counter = 0;
heap->dbg_last_time = 0.0;
/* Send version identification and flush right afterwards. Note that
* we must write raw, unframed bytes here.
*/
duk_push_sprintf(ctx, "%ld %ld %s %s\n",
(long) DUK_DEBUG_PROTOCOL_VERSION,
(long) DUK_VERSION,
(const char *) DUK_GIT_DESCRIBE,
(const char *) DUK_USE_TARGET_INFO);
str = duk_get_lstring(ctx, -1, &len);
DUK_ASSERT(str != NULL);
duk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);
duk_debug_write_flush(thr);
duk_pop(ctx);
}
DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) {
duk_hthread *thr;
DUK_ASSERT_CTX_VALID(ctx);
thr = (duk_hthread *) ctx;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
/* Can be called muliple times with no harm. */
duk_debug_do_detach(thr->heap);
}
DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) {
duk_hthread *thr;
duk_bool_t processed_messages;
DUK_ASSERT_CTX_VALID(ctx);
thr = (duk_hthread *) ctx;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
if (!DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) {
return;
}
if (thr->callstack_top > 0 || thr->heap->dbg_processing) {
/* Calling duk_debugger_cooperate() while Duktape is being
* called into is not supported. This is not a 100% check
* but prevents any damage in most cases.
*/
return;
}
thr->heap->dbg_processing = 1;
processed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);
thr->heap->dbg_processing = 0;
DUK_UNREF(processed_messages);
}
#else /* DUK_USE_DEBUGGER_SUPPORT */
DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
duk_debug_read_function read_cb,
duk_debug_write_function write_cb,
duk_debug_peek_function peek_cb,
duk_debug_read_flush_function read_flush_cb,
duk_debug_write_flush_function write_flush_cb,
duk_debug_detached_function detached_cb,
void *udata) {
DUK_ASSERT_CTX_VALID(ctx);
DUK_UNREF(read_cb);
DUK_UNREF(write_cb);
DUK_UNREF(peek_cb);
DUK_UNREF(read_flush_cb);
DUK_UNREF(write_flush_cb);
DUK_UNREF(detached_cb);
DUK_UNREF(udata);
duk_error(ctx, DUK_ERR_API_ERROR, "no debugger support");
}
DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) {
DUK_ASSERT_CTX_VALID(ctx);
duk_error(ctx, DUK_ERR_API_ERROR, "no debugger support");
}
DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) {
/* nop */
DUK_ASSERT_CTX_VALID(ctx);
DUK_UNREF(ctx);
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */