File: | content/handlers/javascript/duktape/dukky.c |
Warning: | line 1681, column 2 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> | |||
3 | * Copyright 2015 Daniel Dilverstone <dsilvers@netsurf-browser.org> | |||
4 | * Copyright 2016 Michael Drake <tlsa@netsurf-browser.org> | |||
5 | * Copyright 2016 John-Mark Bell <jmb@netsurf-browser.org> | |||
6 | * | |||
7 | * This file is part of NetSurf, http://www.netsurf-browser.org/ | |||
8 | * | |||
9 | * NetSurf is free software; you can redistribute it and/or modify | |||
10 | * it under the terms of the GNU General Public License as published by | |||
11 | * the Free Software Foundation; version 2 of the License. | |||
12 | * | |||
13 | * NetSurf is distributed in the hope that it will be useful, | |||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
16 | * GNU General Public License for more details. | |||
17 | * | |||
18 | * You should have received a copy of the GNU General Public License | |||
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
20 | */ | |||
21 | ||||
22 | /** | |||
23 | * \file | |||
24 | * Duktapeish implementation of javascript engine functions. | |||
25 | */ | |||
26 | ||||
27 | #include <stdint.h> | |||
28 | #include <nsutils/time.h> | |||
29 | ||||
30 | #include "netsurf/inttypes.h" | |||
31 | #include "utils/utils.h" | |||
32 | #include "utils/nsoption.h" | |||
33 | #include "utils/log.h" | |||
34 | #include "utils/corestrings.h" | |||
35 | #include "content/content.h" | |||
36 | ||||
37 | #include "javascript/js.h" | |||
38 | #include "javascript/content.h" | |||
39 | ||||
40 | #include "duktape/binding.h" | |||
41 | #include "duktape/generics.js.inc" | |||
42 | #include "duktape/polyfill.js.inc" | |||
43 | ||||
44 | #include "duktape.h" | |||
45 | #include "dukky.h" | |||
46 | ||||
47 | #include <dom/dom.h> | |||
48 | ||||
49 | #define EVENT_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_MAP") MAGIC(EVENT_MAP)("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_MAP") | |||
50 | #define HANDLER_LISTENER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_LISTENER_MAP") MAGIC(HANDLER_LISTENER_MAP)("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_LISTENER_MAP") | |||
51 | #define HANDLER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP") MAGIC(HANDLER_MAP)("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP") | |||
52 | #define EVENT_LISTENER_JS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_LISTENER_JS_MAP") MAGIC(EVENT_LISTENER_JS_MAP)("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_LISTENER_JS_MAP") | |||
53 | #define GENERICS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "GENERICS_TABLE") MAGIC(GENERICS_TABLE)("\xFF\xFFNETSURF_DUKTAPE_" "GENERICS_TABLE") | |||
54 | #define THREAD_MAP("\xFF\xFFNETSURF_DUKTAPE_" "THREAD_MAP") MAGIC(THREAD_MAP)("\xFF\xFFNETSURF_DUKTAPE_" "THREAD_MAP") | |||
55 | ||||
56 | /** | |||
57 | * dukky javascript heap | |||
58 | */ | |||
59 | struct jsheap { | |||
60 | duk_context *ctx; /**< duktape base context */ | |||
61 | duk_uarridx_t next_thread; /**< monotonic thread counter */ | |||
62 | bool_Bool pending_destroy; /**< Whether this heap is pending destruction */ | |||
63 | unsigned int live_threads; /**< number of live threads */ | |||
64 | uint64_t exec_start_time; | |||
65 | }; | |||
66 | ||||
67 | /** | |||
68 | * dukky javascript thread | |||
69 | */ | |||
70 | struct jsthread { | |||
71 | bool_Bool pending_destroy; /**< Whether this thread is pending destruction */ | |||
72 | unsigned int in_use; /**< The number of times this thread is in use */ | |||
73 | jsheap *heap; /**< The heap this thread belongs to */ | |||
74 | duk_context *ctx; /**< The duktape thread context */ | |||
75 | duk_uarridx_t thread_idx; /**< The thread number */ | |||
76 | }; | |||
77 | ||||
78 | static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata) | |||
79 | { | |||
80 | /* ... obj args protoname nargs */ | |||
81 | int nargs = duk_get_int(ctx, -1); | |||
82 | duk_pop(ctx); | |||
83 | /* ... obj args protoname */ | |||
84 | duk_get_global_string(ctx, PROTO_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPES")); | |||
85 | /* .. obj args protoname prototab */ | |||
86 | duk_dup(ctx, -2); | |||
87 | /* ... obj args protoname prototab protoname */ | |||
88 | duk_get_prop(ctx, -2); | |||
89 | /* ... obj args protoname prototab {proto/undefined} */ | |||
90 | if (duk_is_undefined(ctx, -1)) { | |||
91 | NSLOG(dukky, WARNING,do { if (NSLOG_LEVEL_WARNING >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_WARNING, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 93, }; nslog__log(&_nslog_ctx , "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement" , duk_get_string(ctx, -3) + 2); } } while(0) | |||
92 | "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement",do { if (NSLOG_LEVEL_WARNING >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_WARNING, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 93, }; nslog__log(&_nslog_ctx , "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement" , duk_get_string(ctx, -3) + 2); } } while(0) | |||
93 | duk_get_string(ctx, -3) + 2 /* Skip the two unprintables */)do { if (NSLOG_LEVEL_WARNING >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_WARNING, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 93, }; nslog__log(&_nslog_ctx , "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement" , duk_get_string(ctx, -3) + 2); } } while(0); | |||
94 | duk_pop(ctx); | |||
95 | duk_push_string(ctx, PROTO_NAME(HTMLUNKNOWNELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "HTMLUNKNOWNELEMENT" )); | |||
96 | duk_get_prop(ctx, -2); | |||
97 | } | |||
98 | /* ... obj args protoname prototab proto */ | |||
99 | duk_remove(ctx, -3); | |||
100 | /* ... obj args prototab proto */ | |||
101 | duk_dup(ctx, -1); | |||
102 | /* ... obj args prototab proto proto */ | |||
103 | duk_set_prototype(ctx, -(nargs+4)); | |||
104 | /* ... obj[proto] args prototab proto */ | |||
105 | duk_get_prop_string(ctx, -1, INIT_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "INIT")); | |||
106 | /* ... obj[proto] args prototab proto initfn */ | |||
107 | duk_insert(ctx, -(nargs+4)); | |||
108 | /* ... initfn obj[proto] args prototab proto */ | |||
109 | duk_pop_2(ctx); | |||
110 | /* ... initfn obj[proto] args */ | |||
111 | NSLOG(dukky, DEEPDEBUG, "Call the init function")do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 111, }; nslog__log(&_nslog_ctx , "Call the init function"); } } while(0); | |||
112 | duk_call(ctx, nargs + 1); | |||
113 | return 1; /* The object */ | |||
114 | } | |||
115 | ||||
116 | duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args) | |||
117 | { | |||
118 | duk_ret_t ret; | |||
119 | NSLOG(dukky, DEEPDEBUG, "name=%s nargs=%d", name + 2, args)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 119, }; nslog__log(&_nslog_ctx , "name=%s nargs=%d", name + 2, args); } } while(0); | |||
120 | /* ... args */ | |||
121 | duk_push_object(ctx); | |||
122 | /* ... args obj */ | |||
123 | duk_push_object(ctx); | |||
124 | /* ... args obj handlers */ | |||
125 | duk_put_prop_string(ctx, -2, HANDLER_LISTENER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_LISTENER_MAP")); | |||
126 | /* ... args obj */ | |||
127 | duk_push_object(ctx); | |||
128 | /* ... args obj handlers */ | |||
129 | duk_put_prop_string(ctx, -2, HANDLER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP")); | |||
130 | /* ... args obj */ | |||
131 | duk_insert(ctx, -(args+1)); | |||
132 | /* ... obj args */ | |||
133 | duk_push_string(ctx, name); | |||
134 | /* ... obj args name */ | |||
135 | duk_push_int(ctx, args); | |||
136 | /* ... obj args name nargs */ | |||
137 | if ((ret = duk_safe_call(ctx, dukky_populate_object, NULL((void*)0), args + 3, 1)) | |||
138 | != DUK_EXEC_SUCCESS0) | |||
139 | return ret; | |||
140 | NSLOG(dukky, DEEPDEBUG, "created")do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 140, }; nslog__log(&_nslog_ctx , "created"); } } while(0); | |||
141 | return DUK_EXEC_SUCCESS0; | |||
142 | } | |||
143 | ||||
144 | ||||
145 | ||||
146 | duk_bool_t | |||
147 | dukky_push_node_stacked(duk_context *ctx) | |||
148 | { | |||
149 | int top_at_fail = duk_get_top(ctx) - 2; | |||
150 | /* ... nodeptr klass */ | |||
151 | duk_get_global_string(ctx, NODE_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "NODE_MAP")); | |||
152 | /* ... nodeptr klass nodes */ | |||
153 | duk_dup(ctx, -3); | |||
154 | /* ... nodeptr klass nodes nodeptr */ | |||
155 | duk_get_prop(ctx, -2); | |||
156 | /* ... nodeptr klass nodes node/undefined */ | |||
157 | if (duk_is_undefined(ctx, -1)) { | |||
158 | /* ... nodeptr klass nodes undefined */ | |||
159 | duk_pop(ctx); | |||
160 | /* ... nodeptr klass nodes */ | |||
161 | duk_push_object(ctx); | |||
162 | /* ... nodeptr klass nodes obj */ | |||
163 | duk_push_object(ctx); | |||
164 | /* ... nodeptr klass nodes obj handlers */ | |||
165 | duk_put_prop_string(ctx, -2, HANDLER_LISTENER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_LISTENER_MAP")); | |||
166 | /* ... nodeptr klass nodes obj */ | |||
167 | duk_push_object(ctx); | |||
168 | /* ... nodeptr klass nodes obj handlers */ | |||
169 | duk_put_prop_string(ctx, -2, HANDLER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP")); | |||
170 | /* ... nodeptr klass nodes obj */ | |||
171 | duk_dup(ctx, -4); | |||
172 | /* ... nodeptr klass nodes obj nodeptr */ | |||
173 | duk_dup(ctx, -4); | |||
174 | /* ... nodeptr klass nodes obj nodeptr klass */ | |||
175 | duk_push_int(ctx, 1); | |||
176 | /* ... nodeptr klass nodes obj nodeptr klass 1 */ | |||
177 | if (duk_safe_call(ctx, dukky_populate_object, NULL((void*)0), 4, 1) | |||
178 | != DUK_EXEC_SUCCESS0) { | |||
179 | duk_set_top(ctx, top_at_fail); | |||
180 | NSLOG(dukky, ERROR, "Failed to populate object prototype")do { if (NSLOG_LEVEL_ERROR >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_ERROR, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 180, }; nslog__log(&_nslog_ctx , "Failed to populate object prototype"); } } while(0); | |||
181 | return false0; | |||
182 | } | |||
183 | /* ... nodeptr klass nodes node */ | |||
184 | duk_dup(ctx, -4); | |||
185 | /* ... nodeptr klass nodes node nodeptr */ | |||
186 | duk_dup(ctx, -2); | |||
187 | /* ... nodeptr klass nodes node nodeptr node */ | |||
188 | duk_put_prop(ctx, -4); | |||
189 | /* ... nodeptr klass nodes node */ | |||
190 | } | |||
191 | /* ... nodeptr klass nodes node */ | |||
192 | duk_insert(ctx, -4); | |||
193 | /* ... node nodeptr klass nodes */ | |||
194 | duk_pop_3(ctx); | |||
195 | /* ... node */ | |||
196 | if (NSLOG_COMPILED_MIN_LEVELNSLOG_LEVEL_VERBOSE <= NSLOG_LEVEL_DEEPDEBUG) { | |||
197 | duk_dup(ctx, -1); | |||
198 | const char * what = duk_safe_to_string(ctx, -1)duk_safe_to_lstring((ctx), (-1), ((void*)0)); | |||
199 | NSLOG(dukky, DEEPDEBUG, "Created: %s", what)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 199, }; nslog__log(&_nslog_ctx , "Created: %s", what); } } while(0); | |||
200 | duk_pop(ctx); | |||
201 | } | |||
202 | return true1; | |||
203 | } | |||
204 | ||||
205 | #define SET_HTML_CLASS(CLASS) \ | |||
206 | *html_class = PROTO_NAME(HTML##CLASS##ELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "HTML##CLASS##ELEMENT" ); \ | |||
207 | *html_class_len = \ | |||
208 | SLEN(PROTO_NAME(HTML))(sizeof((("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "HTML"))) - 1) + \ | |||
209 | SLEN(#CLASS)(sizeof((#CLASS)) - 1) + \ | |||
210 | SLEN("ELEMENT")(sizeof(("ELEMENT")) - 1); | |||
211 | ||||
212 | static void dukky_html_element_class_from_tag_type(dom_html_element_type type, | |||
213 | const char **html_class, size_t *html_class_len) | |||
214 | { | |||
215 | switch(type) { | |||
216 | case DOM_HTML_ELEMENT_TYPE_HTML: | |||
217 | SET_HTML_CLASS(HTML) | |||
218 | break; | |||
219 | case DOM_HTML_ELEMENT_TYPE_HEAD: | |||
220 | SET_HTML_CLASS(HEAD) | |||
221 | break; | |||
222 | case DOM_HTML_ELEMENT_TYPE_META: | |||
223 | SET_HTML_CLASS(META) | |||
224 | break; | |||
225 | case DOM_HTML_ELEMENT_TYPE_BASE: | |||
226 | SET_HTML_CLASS(BASE) | |||
227 | break; | |||
228 | case DOM_HTML_ELEMENT_TYPE_TITLE: | |||
229 | SET_HTML_CLASS(TITLE) | |||
230 | break; | |||
231 | case DOM_HTML_ELEMENT_TYPE_BODY: | |||
232 | SET_HTML_CLASS(BODY) | |||
233 | break; | |||
234 | case DOM_HTML_ELEMENT_TYPE_DIV: | |||
235 | SET_HTML_CLASS(DIV) | |||
236 | break; | |||
237 | case DOM_HTML_ELEMENT_TYPE_FORM: | |||
238 | SET_HTML_CLASS(FORM) | |||
239 | break; | |||
240 | case DOM_HTML_ELEMENT_TYPE_LINK: | |||
241 | SET_HTML_CLASS(LINK) | |||
242 | break; | |||
243 | case DOM_HTML_ELEMENT_TYPE_BUTTON: | |||
244 | SET_HTML_CLASS(BUTTON) | |||
245 | break; | |||
246 | case DOM_HTML_ELEMENT_TYPE_INPUT: | |||
247 | SET_HTML_CLASS(INPUT) | |||
248 | break; | |||
249 | case DOM_HTML_ELEMENT_TYPE_TEXTAREA: | |||
250 | SET_HTML_CLASS(TEXTAREA) | |||
251 | break; | |||
252 | case DOM_HTML_ELEMENT_TYPE_OPTGROUP: | |||
253 | SET_HTML_CLASS(OPTGROUP) | |||
254 | break; | |||
255 | case DOM_HTML_ELEMENT_TYPE_OPTION: | |||
256 | SET_HTML_CLASS(OPTION) | |||
257 | break; | |||
258 | case DOM_HTML_ELEMENT_TYPE_SELECT: | |||
259 | SET_HTML_CLASS(SELECT) | |||
260 | break; | |||
261 | case DOM_HTML_ELEMENT_TYPE_HR: | |||
262 | SET_HTML_CLASS(HR) | |||
263 | break; | |||
264 | case DOM_HTML_ELEMENT_TYPE_DL: | |||
265 | SET_HTML_CLASS(DLIST) | |||
266 | break; | |||
267 | case DOM_HTML_ELEMENT_TYPE_DIR: | |||
268 | SET_HTML_CLASS(DIRECTORY) | |||
269 | break; | |||
270 | case DOM_HTML_ELEMENT_TYPE_MENU: | |||
271 | SET_HTML_CLASS(MENU) | |||
272 | break; | |||
273 | case DOM_HTML_ELEMENT_TYPE_FIELDSET: | |||
274 | SET_HTML_CLASS(FIELDSET) | |||
275 | break; | |||
276 | case DOM_HTML_ELEMENT_TYPE_LEGEND: | |||
277 | SET_HTML_CLASS(LEGEND) | |||
278 | break; | |||
279 | case DOM_HTML_ELEMENT_TYPE_P: | |||
280 | SET_HTML_CLASS(PARAGRAPH) | |||
281 | break; | |||
282 | case DOM_HTML_ELEMENT_TYPE_H1: | |||
283 | case DOM_HTML_ELEMENT_TYPE_H2: | |||
284 | case DOM_HTML_ELEMENT_TYPE_H3: | |||
285 | case DOM_HTML_ELEMENT_TYPE_H4: | |||
286 | case DOM_HTML_ELEMENT_TYPE_H5: | |||
287 | case DOM_HTML_ELEMENT_TYPE_H6: | |||
288 | SET_HTML_CLASS(HEADING) | |||
289 | break; | |||
290 | case DOM_HTML_ELEMENT_TYPE_BLOCKQUOTE: | |||
291 | case DOM_HTML_ELEMENT_TYPE_Q: | |||
292 | SET_HTML_CLASS(QUOTE) | |||
293 | break; | |||
294 | case DOM_HTML_ELEMENT_TYPE_PRE: | |||
295 | SET_HTML_CLASS(PRE) | |||
296 | break; | |||
297 | case DOM_HTML_ELEMENT_TYPE_BR: | |||
298 | SET_HTML_CLASS(BR) | |||
299 | break; | |||
300 | case DOM_HTML_ELEMENT_TYPE_LABEL: | |||
301 | SET_HTML_CLASS(LABEL) | |||
302 | break; | |||
303 | case DOM_HTML_ELEMENT_TYPE_UL: | |||
304 | SET_HTML_CLASS(ULIST) | |||
305 | break; | |||
306 | case DOM_HTML_ELEMENT_TYPE_OL: | |||
307 | SET_HTML_CLASS(OLIST) | |||
308 | break; | |||
309 | case DOM_HTML_ELEMENT_TYPE_LI: | |||
310 | SET_HTML_CLASS(LI) | |||
311 | break; | |||
312 | case DOM_HTML_ELEMENT_TYPE_FONT: | |||
313 | SET_HTML_CLASS(FONT) | |||
314 | break; | |||
315 | case DOM_HTML_ELEMENT_TYPE_DEL: | |||
316 | case DOM_HTML_ELEMENT_TYPE_INS: | |||
317 | SET_HTML_CLASS(MOD) | |||
318 | break; | |||
319 | case DOM_HTML_ELEMENT_TYPE_A: | |||
320 | SET_HTML_CLASS(ANCHOR) | |||
321 | break; | |||
322 | case DOM_HTML_ELEMENT_TYPE_BASEFONT: | |||
323 | SET_HTML_CLASS(BASEFONT) | |||
324 | break; | |||
325 | case DOM_HTML_ELEMENT_TYPE_IMG: | |||
326 | SET_HTML_CLASS(IMAGE) | |||
327 | break; | |||
328 | case DOM_HTML_ELEMENT_TYPE_OBJECT: | |||
329 | SET_HTML_CLASS(OBJECT) | |||
330 | break; | |||
331 | case DOM_HTML_ELEMENT_TYPE_PARAM: | |||
332 | SET_HTML_CLASS(PARAM) | |||
333 | break; | |||
334 | case DOM_HTML_ELEMENT_TYPE_APPLET: | |||
335 | SET_HTML_CLASS(APPLET) | |||
336 | break; | |||
337 | case DOM_HTML_ELEMENT_TYPE_MAP: | |||
338 | SET_HTML_CLASS(MAP) | |||
339 | break; | |||
340 | case DOM_HTML_ELEMENT_TYPE_AREA: | |||
341 | SET_HTML_CLASS(AREA) | |||
342 | break; | |||
343 | case DOM_HTML_ELEMENT_TYPE_SCRIPT: | |||
344 | SET_HTML_CLASS(SCRIPT) | |||
345 | break; | |||
346 | case DOM_HTML_ELEMENT_TYPE_CAPTION: | |||
347 | SET_HTML_CLASS(TABLECAPTION) | |||
348 | break; | |||
349 | case DOM_HTML_ELEMENT_TYPE_TD: | |||
350 | case DOM_HTML_ELEMENT_TYPE_TH: | |||
351 | SET_HTML_CLASS(TABLECELL) | |||
352 | break; | |||
353 | case DOM_HTML_ELEMENT_TYPE_COL: | |||
354 | case DOM_HTML_ELEMENT_TYPE_COLGROUP: | |||
355 | SET_HTML_CLASS(TABLECOL) | |||
356 | break; | |||
357 | case DOM_HTML_ELEMENT_TYPE_THEAD: | |||
358 | case DOM_HTML_ELEMENT_TYPE_TBODY: | |||
359 | case DOM_HTML_ELEMENT_TYPE_TFOOT: | |||
360 | SET_HTML_CLASS(TABLESECTION) | |||
361 | break; | |||
362 | case DOM_HTML_ELEMENT_TYPE_TABLE: | |||
363 | SET_HTML_CLASS(TABLE) | |||
364 | break; | |||
365 | case DOM_HTML_ELEMENT_TYPE_TR: | |||
366 | SET_HTML_CLASS(TABLEROW) | |||
367 | break; | |||
368 | case DOM_HTML_ELEMENT_TYPE_STYLE: | |||
369 | SET_HTML_CLASS(STYLE) | |||
370 | break; | |||
371 | case DOM_HTML_ELEMENT_TYPE_FRAMESET: | |||
372 | SET_HTML_CLASS(FRAMESET) | |||
373 | break; | |||
374 | case DOM_HTML_ELEMENT_TYPE_FRAME: | |||
375 | SET_HTML_CLASS(FRAME) | |||
376 | break; | |||
377 | case DOM_HTML_ELEMENT_TYPE_IFRAME: | |||
378 | SET_HTML_CLASS(IFRAME) | |||
379 | break; | |||
380 | case DOM_HTML_ELEMENT_TYPE_ISINDEX: | |||
381 | SET_HTML_CLASS(ISINDEX) | |||
382 | break; | |||
383 | case DOM_HTML_ELEMENT_TYPE_CANVAS: | |||
384 | SET_HTML_CLASS(CANVAS) | |||
385 | break; | |||
386 | case DOM_HTML_ELEMENT_TYPE__COUNT: | |||
387 | assert(type != DOM_HTML_ELEMENT_TYPE__COUNT)((type != DOM_HTML_ELEMENT_TYPE__COUNT) ? (void) (0) : __assert_fail ("type != DOM_HTML_ELEMENT_TYPE__COUNT", "content/handlers/javascript/duktape/dukky.c" , 387, __extension__ __PRETTY_FUNCTION__)); | |||
388 | fallthrough__attribute__((__fallthrough__)); | |||
389 | case DOM_HTML_ELEMENT_TYPE__UNKNOWN: | |||
390 | SET_HTML_CLASS(UNKNOWN) | |||
391 | break; | |||
392 | default: | |||
393 | /* Known HTML element without a specialisation */ | |||
394 | *html_class = PROTO_NAME(HTMLELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "HTMLELEMENT"); | |||
395 | *html_class_len = | |||
396 | SLEN(PROTO_NAME(HTML))(sizeof((("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "HTML"))) - 1) + | |||
397 | SLEN("ELEMENT")(sizeof(("ELEMENT")) - 1); | |||
398 | break; | |||
399 | } | |||
400 | return; | |||
401 | } | |||
402 | ||||
403 | #undef SET_HTML_CLASS | |||
404 | ||||
405 | static void | |||
406 | dukky_push_node_klass(duk_context *ctx, struct dom_node *node) | |||
407 | { | |||
408 | dom_node_type nodetype; | |||
409 | dom_exception err; | |||
410 | ||||
411 | err = dom_node_get_node_type(node, &nodetype)dom_node_get_node_type( (dom_node *) (node), (dom_node_type * ) (&nodetype)); | |||
412 | if (err != DOM_NO_ERR) { | |||
413 | /* Oh bum, just node then */ | |||
414 | duk_push_string(ctx, PROTO_NAME(NODE)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "NODE")); | |||
415 | return; | |||
416 | } | |||
417 | ||||
418 | switch(nodetype) { | |||
419 | case DOM_ELEMENT_NODE: { | |||
420 | dom_string *namespace; | |||
421 | dom_html_element_type type; | |||
422 | const char *html_class; | |||
423 | size_t html_class_len; | |||
424 | err = dom_node_get_namespace(node, &namespace)dom_node_get_namespace((dom_node *) (node), (&namespace)); | |||
425 | if (err != DOM_NO_ERR) { | |||
426 | /* Feck it, element */ | |||
427 | NSLOG(dukky, ERROR,do { if (NSLOG_LEVEL_ERROR >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_ERROR, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 428, }; nslog__log(&_nslog_ctx , "dom_node_get_namespace() failed"); } } while(0) | |||
428 | "dom_node_get_namespace() failed")do { if (NSLOG_LEVEL_ERROR >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_ERROR, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 428, }; nslog__log(&_nslog_ctx , "dom_node_get_namespace() failed"); } } while(0); | |||
429 | duk_push_string(ctx, PROTO_NAME(ELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "ELEMENT")); | |||
430 | break; | |||
431 | } | |||
432 | if (namespace == NULL((void*)0)) { | |||
433 | /* No namespace, -> element */ | |||
434 | NSLOG(dukky, DEBUG, "no namespace")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 434, }; nslog__log(&_nslog_ctx , "no namespace"); } } while(0); | |||
435 | duk_push_string(ctx, PROTO_NAME(ELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "ELEMENT")); | |||
436 | break; | |||
437 | } | |||
438 | ||||
439 | if (dom_string_isequal(namespace, corestring_dom_html_namespace) == false0) { | |||
440 | /* definitely not an HTML element of some kind */ | |||
441 | duk_push_string(ctx, PROTO_NAME(ELEMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "ELEMENT")); | |||
442 | dom_string_unref(namespace); | |||
443 | break; | |||
444 | } | |||
445 | dom_string_unref(namespace); | |||
446 | ||||
447 | err = dom_html_element_get_tag_type(node, &type)dom_html_element_get_tag_type((const dom_html_element *) (node ), (&type)); | |||
448 | if (err != DOM_NO_ERR) { | |||
449 | type = DOM_HTML_ELEMENT_TYPE__UNKNOWN; | |||
450 | } | |||
451 | ||||
452 | dukky_html_element_class_from_tag_type(type, | |||
453 | &html_class, &html_class_len); | |||
454 | ||||
455 | duk_push_lstring(ctx, html_class, html_class_len); | |||
456 | break; | |||
457 | } | |||
458 | case DOM_TEXT_NODE: | |||
459 | duk_push_string(ctx, PROTO_NAME(TEXT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "TEXT")); | |||
460 | break; | |||
461 | case DOM_COMMENT_NODE: | |||
462 | duk_push_string(ctx, PROTO_NAME(COMMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "COMMENT")); | |||
463 | break; | |||
464 | case DOM_DOCUMENT_NODE: | |||
465 | duk_push_string(ctx, PROTO_NAME(DOCUMENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "DOCUMENT")); | |||
466 | break; | |||
467 | case DOM_ATTRIBUTE_NODE: | |||
468 | case DOM_PROCESSING_INSTRUCTION_NODE: | |||
469 | case DOM_DOCUMENT_TYPE_NODE: | |||
470 | case DOM_DOCUMENT_FRAGMENT_NODE: | |||
471 | case DOM_NOTATION_NODE: | |||
472 | case DOM_ENTITY_REFERENCE_NODE: | |||
473 | case DOM_ENTITY_NODE: | |||
474 | case DOM_CDATA_SECTION_NODE: | |||
475 | default: | |||
476 | /* Oh bum, just node then */ | |||
477 | duk_push_string(ctx, PROTO_NAME(NODE)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "NODE")); | |||
478 | } | |||
479 | } | |||
480 | ||||
481 | duk_bool_t | |||
482 | dukky_push_node(duk_context *ctx, struct dom_node *node) | |||
483 | { | |||
484 | NSLOG(dukky, DEEPDEBUG, "Pushing node %p", node)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 484, }; nslog__log(&_nslog_ctx , "Pushing node %p", node); } } while(0); | |||
485 | /* First check if we can find the node */ | |||
486 | /* ... */ | |||
487 | duk_get_global_string(ctx, NODE_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "NODE_MAP")); | |||
488 | /* ... nodes */ | |||
489 | duk_push_pointer(ctx, node); | |||
490 | /* ... nodes nodeptr */ | |||
491 | duk_get_prop(ctx, -2); | |||
492 | /* ... nodes node/undefined */ | |||
493 | if (!duk_is_undefined(ctx, -1)) { | |||
494 | /* ... nodes node */ | |||
495 | duk_insert(ctx, -2); | |||
496 | /* ... node nodes */ | |||
497 | duk_pop(ctx); | |||
498 | /* ... node */ | |||
499 | if (NSLOG_COMPILED_MIN_LEVELNSLOG_LEVEL_VERBOSE <= NSLOG_LEVEL_DEEPDEBUG) { | |||
500 | duk_dup(ctx, -1); | |||
501 | const char * what = duk_safe_to_string(ctx, -1)duk_safe_to_lstring((ctx), (-1), ((void*)0)); | |||
502 | NSLOG(dukky, DEEPDEBUG, "Found it memoised: %s", what)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 502, }; nslog__log(&_nslog_ctx , "Found it memoised: %s", what); } } while(0); | |||
503 | duk_pop(ctx); | |||
504 | } | |||
505 | return true1; | |||
506 | } | |||
507 | /* ... nodes undefined */ | |||
508 | duk_pop_2(ctx); | |||
509 | /* ... */ | |||
510 | /* We couldn't, so now we determine the node type and then | |||
511 | * we ask for it to be created | |||
512 | */ | |||
513 | duk_push_pointer(ctx, node); | |||
514 | /* ... nodeptr */ | |||
515 | dukky_push_node_klass(ctx, node); | |||
516 | /* ... nodeptr klass */ | |||
517 | return dukky_push_node_stacked(ctx); | |||
518 | } | |||
519 | ||||
520 | static duk_ret_t | |||
521 | dukky_bad_constructor(duk_context *ctx) | |||
522 | { | |||
523 | return duk_error(ctx, DUK_ERR_ERROR, "Bad constructor")(duk_error_raw((ctx), (duk_errcode_t) (1), (const char *) ("content/handlers/javascript/duktape/dukky.c" ), (duk_int_t) (523), "Bad constructor"), (duk_ret_t) 0); | |||
524 | } | |||
525 | ||||
526 | void | |||
527 | dukky_inject_not_ctr(duk_context *ctx, int idx, const char *name) | |||
528 | { | |||
529 | /* ... p[idx] ... proto */ | |||
530 | duk_push_c_function(ctx, dukky_bad_constructor, 0); | |||
531 | /* ... p[idx] ... proto cons */ | |||
532 | duk_insert(ctx, -2); | |||
533 | /* ... p[idx] ... cons proto */ | |||
534 | duk_put_prop_string(ctx, -2, "prototype"); | |||
535 | /* ... p[idx] ... cons[proto] */ | |||
536 | duk_put_prop_string(ctx, idx, name); | |||
537 | /* ... p ... */ | |||
538 | return; | |||
539 | } | |||
540 | ||||
541 | /* Duktape heap utility functions */ | |||
542 | ||||
543 | /* We need to override the defaults because not all platforms are fully ANSI | |||
544 | * compatible. E.g. RISC OS gets upset if we malloc or realloc a zero byte | |||
545 | * block, as do debugging tools such as Electric Fence by Bruce Perens. | |||
546 | */ | |||
547 | ||||
548 | static void *dukky_alloc_function(void *udata, duk_size_t size) | |||
549 | { | |||
550 | if (size == 0) | |||
551 | return NULL((void*)0); | |||
552 | ||||
553 | return malloc(size); | |||
554 | } | |||
555 | ||||
556 | static void *dukky_realloc_function(void *udata, void *ptr, duk_size_t size) | |||
557 | { | |||
558 | if (ptr == NULL((void*)0) && size == 0) | |||
559 | return NULL((void*)0); | |||
560 | ||||
561 | if (size == 0) { | |||
562 | free(ptr); | |||
563 | return NULL((void*)0); | |||
564 | } | |||
565 | ||||
566 | return realloc(ptr, size); | |||
567 | } | |||
568 | ||||
569 | ||||
570 | static void dukky_free_function(void *udata, void *ptr) | |||
571 | { | |||
572 | if (ptr != NULL((void*)0)) | |||
573 | free(ptr); | |||
574 | } | |||
575 | ||||
576 | /* exported interface documented in js.h */ | |||
577 | void js_initialise(void) | |||
578 | { | |||
579 | /** TODO: Forces JS on for our testing, needs changing before a release | |||
580 | * lest we incur the wrath of others. | |||
581 | */ | |||
582 | /* Disabled force-on for forthcoming release */ | |||
583 | /* nsoption_set_bool(enable_javascript, true); | |||
584 | */ | |||
585 | javascript_init(); | |||
586 | } | |||
587 | ||||
588 | ||||
589 | /* exported interface documented in js.h */ | |||
590 | void js_finalise(void) | |||
591 | { | |||
592 | /* NADA for now */ | |||
593 | } | |||
594 | ||||
595 | ||||
596 | /* exported interface documented in js.h */ | |||
597 | nserror | |||
598 | js_newheap(int timeout, jsheap **heap) | |||
599 | { | |||
600 | duk_context *ctx; | |||
601 | jsheap *ret = calloc(1, sizeof(*ret)); | |||
602 | *heap = NULL((void*)0); | |||
603 | NSLOG(dukky, DEBUG, "Creating new duktape javascript heap")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 603, }; nslog__log(&_nslog_ctx , "Creating new duktape javascript heap"); } } while(0); | |||
604 | if (ret == NULL((void*)0)) return NSERROR_NOMEM; | |||
605 | ctx = ret->ctx = duk_create_heap( | |||
606 | dukky_alloc_function, | |||
607 | dukky_realloc_function, | |||
608 | dukky_free_function, | |||
609 | ret, | |||
610 | NULL((void*)0)); | |||
611 | if (ret->ctx == NULL((void*)0)) { free(ret); return NSERROR_NOMEM; } | |||
612 | /* Create the prototype stuffs */ | |||
613 | duk_push_global_object(ctx); | |||
614 | duk_push_boolean(ctx, true1); | |||
615 | duk_put_prop_string(ctx, -2, "protos"); | |||
616 | duk_put_global_string(ctx, PROTO_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPES")); | |||
617 | /* Create prototypes here */ | |||
618 | dukky_create_prototypes(ctx); | |||
619 | /* Now create the thread map */ | |||
620 | duk_push_object(ctx); | |||
621 | duk_put_global_string(ctx, THREAD_MAP("\xFF\xFFNETSURF_DUKTAPE_" "THREAD_MAP")); | |||
622 | ||||
623 | *heap = ret; | |||
624 | return NSERROR_OK; | |||
625 | } | |||
626 | ||||
627 | ||||
628 | static void dukky_destroyheap(jsheap *heap) | |||
629 | { | |||
630 | assert(heap->pending_destroy == true)((heap->pending_destroy == 1) ? (void) (0) : __assert_fail ("heap->pending_destroy == true", "content/handlers/javascript/duktape/dukky.c" , 630, __extension__ __PRETTY_FUNCTION__)); | |||
631 | assert(heap->live_threads == 0)((heap->live_threads == 0) ? (void) (0) : __assert_fail ("heap->live_threads == 0" , "content/handlers/javascript/duktape/dukky.c", 631, __extension__ __PRETTY_FUNCTION__)); | |||
632 | NSLOG(dukky, DEBUG, "Destroying duktape javascript context")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 632, }; nslog__log(&_nslog_ctx , "Destroying duktape javascript context"); } } while(0); | |||
633 | duk_destroy_heap(heap->ctx); | |||
634 | free(heap); | |||
635 | } | |||
636 | ||||
637 | /* exported interface documented in js.h */ | |||
638 | void js_destroyheap(jsheap *heap) | |||
639 | { | |||
640 | heap->pending_destroy = true1; | |||
641 | if (heap->live_threads == 0) { | |||
642 | dukky_destroyheap(heap); | |||
643 | } | |||
644 | } | |||
645 | ||||
646 | /* Just for here, the CTX is in ret, not thread */ | |||
647 | #define CTX(thread->ctx) (ret->ctx) | |||
648 | ||||
649 | /* exported interface documented in js.h */ | |||
650 | nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread **thread) | |||
651 | { | |||
652 | jsthread *ret; | |||
653 | assert(heap != NULL)((heap != ((void*)0)) ? (void) (0) : __assert_fail ("heap != NULL" , "content/handlers/javascript/duktape/dukky.c", 653, __extension__ __PRETTY_FUNCTION__)); | |||
654 | assert(heap->pending_destroy == false)((heap->pending_destroy == 0) ? (void) (0) : __assert_fail ("heap->pending_destroy == false", "content/handlers/javascript/duktape/dukky.c" , 654, __extension__ __PRETTY_FUNCTION__)); | |||
655 | ||||
656 | ret = calloc(1, sizeof (*ret)); | |||
657 | if (ret == NULL((void*)0)) { | |||
658 | NSLOG(dukky, ERROR, "Unable to allocate new JS thread structure")do { if (NSLOG_LEVEL_ERROR >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_ERROR, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 658, }; nslog__log(&_nslog_ctx , "Unable to allocate new JS thread structure"); } } while(0); | |||
659 | return NSERROR_NOMEM; | |||
660 | } | |||
661 | ||||
662 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 664, }; nslog__log(&_nslog_ctx , "New javascript/duktape thread, win_priv=%p, doc_priv=%p", win_priv , doc_priv); } } while(0) | |||
663 | "New javascript/duktape thread, win_priv=%p, doc_priv=%p",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 664, }; nslog__log(&_nslog_ctx , "New javascript/duktape thread, win_priv=%p, doc_priv=%p", win_priv , doc_priv); } } while(0) | |||
664 | win_priv, doc_priv)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 664, }; nslog__log(&_nslog_ctx , "New javascript/duktape thread, win_priv=%p, doc_priv=%p", win_priv , doc_priv); } } while(0); | |||
665 | ||||
666 | /* create new thread */ | |||
667 | duk_get_global_string(heap->ctx, THREAD_MAP("\xFF\xFFNETSURF_DUKTAPE_" "THREAD_MAP")); /* ... threads */ | |||
668 | duk_push_thread(heap->ctx)duk_push_thread_raw((heap->ctx), 0 ); /* ... threads thread */ | |||
669 | ret->heap = heap; | |||
670 | ret->ctx = duk_require_context(heap->ctx, -1); | |||
671 | ret->thread_idx = heap->next_thread++; | |||
672 | duk_put_prop_index(heap->ctx, -2, ret->thread_idx); | |||
673 | heap->live_threads++; | |||
674 | duk_pop(heap->ctx); /* ... */ | |||
675 | duk_push_int(CTX(thread->ctx), 0); | |||
676 | duk_push_int(CTX(thread->ctx), 1); | |||
677 | duk_push_int(CTX(thread->ctx), 2); | |||
678 | /* Manufacture a Window object */ | |||
679 | /* win_priv is a browser_window, doc_priv is an html content struct */ | |||
680 | duk_push_pointer(CTX(thread->ctx), win_priv); | |||
681 | duk_push_pointer(CTX(thread->ctx), doc_priv); | |||
682 | dukky_create_object(CTX(thread->ctx), PROTO_NAME(WINDOW)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "WINDOW"), 2); | |||
683 | duk_push_global_object(CTX(thread->ctx)); | |||
684 | duk_put_prop_string(CTX(thread->ctx), -2, PROTO_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPES")); | |||
685 | duk_set_global_object(CTX(thread->ctx)); | |||
686 | ||||
687 | /* Now we need to prepare our node mapping table */ | |||
688 | duk_push_object(CTX(thread->ctx)); | |||
689 | duk_push_pointer(CTX(thread->ctx), NULL((void*)0)); | |||
690 | duk_push_null(CTX(thread->ctx)); | |||
691 | duk_put_prop(CTX(thread->ctx), -3); | |||
692 | duk_put_global_string(CTX(thread->ctx), NODE_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "NODE_MAP")); | |||
693 | ||||
694 | /* And now the event mapping table */ | |||
695 | duk_push_object(CTX(thread->ctx)); | |||
696 | duk_put_global_string(CTX(thread->ctx), EVENT_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_MAP")); | |||
697 | ||||
698 | /* Now load the polyfills */ | |||
699 | /* ... */ | |||
700 | duk_push_string(CTX(thread->ctx), "polyfill.js"); | |||
701 | /* ..., polyfill.js */ | |||
702 | if (duk_pcompile_lstring_filename(CTX, DUK_COMPILE_EVAL,(duk_compile_raw(((thread->ctx)), (const char *)polyfill_js , polyfill_js_len, 1 | ((1U << 3)) | (1U << 7) | ( 1U << 9))) | |||
703 | (const char *)polyfill_js, polyfill_js_len)(duk_compile_raw(((thread->ctx)), (const char *)polyfill_js , polyfill_js_len, 1 | ((1U << 3)) | (1U << 7) | ( 1U << 9))) != 0) { | |||
704 | NSLOG(dukky, CRITICAL, "%s", duk_safe_to_string(CTX, -1))do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 704, }; nslog__log(&_nslog_ctx , "%s", duk_safe_to_lstring(((thread->ctx)), (-1), ((void* )0))); } } while(0); | |||
705 | NSLOG(dukky, CRITICAL, "Unable to compile polyfill.js, thread aborted")do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 705, }; nslog__log(&_nslog_ctx , "Unable to compile polyfill.js, thread aborted"); } } while (0); | |||
706 | js_destroythread(ret); | |||
707 | return NSERROR_INIT_FAILED; | |||
708 | } | |||
709 | /* ..., (generics.js) */ | |||
710 | if (dukky_pcall(CTX(thread->ctx), 0, true1) != 0) { | |||
711 | NSLOG(dukky, CRITICAL, "Unable to run polyfill.js, thread aborted")do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 711, }; nslog__log(&_nslog_ctx , "Unable to run polyfill.js, thread aborted"); } } while(0); | |||
712 | js_destroythread(ret); | |||
713 | return NSERROR_INIT_FAILED; | |||
714 | } | |||
715 | /* ..., result */ | |||
716 | duk_pop(CTX(thread->ctx)); | |||
717 | /* ... */ | |||
718 | ||||
719 | /* Now load the NetSurf table in */ | |||
720 | /* ... */ | |||
721 | duk_push_string(CTX(thread->ctx), "generics.js"); | |||
722 | /* ..., generics.js */ | |||
723 | if (duk_pcompile_lstring_filename(CTX, DUK_COMPILE_EVAL,(duk_compile_raw(((thread->ctx)), (const char *)generics_js , generics_js_len, 1 | ((1U << 3)) | (1U << 7) | ( 1U << 9))) | |||
724 | (const char *)generics_js, generics_js_len)(duk_compile_raw(((thread->ctx)), (const char *)generics_js , generics_js_len, 1 | ((1U << 3)) | (1U << 7) | ( 1U << 9))) != 0) { | |||
725 | NSLOG(dukky, CRITICAL, "%s", duk_safe_to_string(CTX, -1))do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 725, }; nslog__log(&_nslog_ctx , "%s", duk_safe_to_lstring(((thread->ctx)), (-1), ((void* )0))); } } while(0); | |||
726 | NSLOG(dukky, CRITICAL, "Unable to compile generics.js, thread aborted")do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 726, }; nslog__log(&_nslog_ctx , "Unable to compile generics.js, thread aborted"); } } while (0); | |||
727 | js_destroythread(ret); | |||
728 | return NSERROR_INIT_FAILED; | |||
729 | } | |||
730 | /* ..., (generics.js) */ | |||
731 | if (dukky_pcall(CTX(thread->ctx), 0, true1) != 0) { | |||
732 | NSLOG(dukky, CRITICAL, "Unable to run generics.js, thread aborted")do { if (NSLOG_LEVEL_CRITICAL >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_CRITICAL, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 732, }; nslog__log(&_nslog_ctx , "Unable to run generics.js, thread aborted"); } } while(0); | |||
733 | js_destroythread(ret); | |||
734 | return NSERROR_INIT_FAILED; | |||
735 | } | |||
736 | /* ..., result */ | |||
737 | duk_pop(CTX(thread->ctx)); | |||
738 | /* ... */ | |||
739 | duk_push_global_object(CTX(thread->ctx)); | |||
740 | /* ..., Win */ | |||
741 | duk_get_prop_string(CTX(thread->ctx), -1, "NetSurf"); | |||
742 | /* ..., Win, NetSurf */ | |||
743 | duk_put_global_string(CTX(thread->ctx), GENERICS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "GENERICS_TABLE")); | |||
744 | /* ..., Win */ | |||
745 | duk_del_prop_string(CTX(thread->ctx), -1, "NetSurf"); | |||
746 | duk_pop(CTX(thread->ctx)); | |||
747 | /* ... */ | |||
748 | ||||
749 | dukky_log_stack_frame(CTX(thread->ctx), "New thread created"); | |||
750 | NSLOG(dukky, DEBUG, "New thread is %p in heap %p", thread, heap)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 750, }; nslog__log(&_nslog_ctx , "New thread is %p in heap %p", thread, heap); } } while(0); | |||
751 | *thread = ret; | |||
752 | ||||
753 | return NSERROR_OK; | |||
754 | } | |||
755 | ||||
756 | /* Now switch to the long term CTX behaviour */ | |||
757 | #undef CTX(thread->ctx) | |||
758 | #define CTX(thread->ctx) (thread->ctx) | |||
759 | ||||
760 | /* exported interface documented in js.h */ | |||
761 | nserror js_closethread(jsthread *thread) | |||
762 | { | |||
763 | /* We can always close down a thread, it might just confuse | |||
764 | * the code running, though we don't mind since we're in the | |||
765 | * process of destruction at this point | |||
766 | */ | |||
767 | duk_int_t top = duk_get_top(CTX(thread->ctx)); | |||
768 | ||||
769 | /* Closing down the extant thread */ | |||
770 | NSLOG(dukky, DEBUG, "Closing down extant thread %p in heap %p", thread, thread->heap)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 770, }; nslog__log(&_nslog_ctx , "Closing down extant thread %p in heap %p", thread, thread-> heap); } } while(0); | |||
771 | duk_get_global_string(CTX(thread->ctx), MAGIC(closedownThread)("\xFF\xFFNETSURF_DUKTAPE_" "closedownThread")); | |||
772 | dukky_pcall(CTX(thread->ctx), 0, true1); | |||
773 | ||||
774 | /* Restore whatever stack we had */ | |||
775 | duk_set_top(CTX(thread->ctx), top); | |||
776 | ||||
777 | return NSERROR_OK; | |||
778 | } | |||
779 | ||||
780 | /** | |||
781 | * Destroy a Duktape thread | |||
782 | */ | |||
783 | static void dukky_destroythread(jsthread *thread) | |||
784 | { | |||
785 | jsheap *heap = thread->heap; | |||
786 | ||||
787 | assert(thread->in_use == 0)((thread->in_use == 0) ? (void) (0) : __assert_fail ("thread->in_use == 0" , "content/handlers/javascript/duktape/dukky.c", 787, __extension__ __PRETTY_FUNCTION__)); | |||
788 | assert(thread->pending_destroy == true)((thread->pending_destroy == 1) ? (void) (0) : __assert_fail ("thread->pending_destroy == true", "content/handlers/javascript/duktape/dukky.c" , 788, __extension__ __PRETTY_FUNCTION__)); | |||
789 | ||||
790 | /* Closing down the extant thread */ | |||
791 | NSLOG(dukky, DEBUG, "Closing down extant thread %p in heap %p", thread, heap)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 791, }; nslog__log(&_nslog_ctx , "Closing down extant thread %p in heap %p", thread, heap); } } while(0); | |||
792 | duk_get_global_string(CTX(thread->ctx), MAGIC(closedownThread)("\xFF\xFFNETSURF_DUKTAPE_" "closedownThread")); | |||
793 | dukky_pcall(CTX(thread->ctx), 0, true1); | |||
794 | ||||
795 | /* Now delete the thread from the heap */ | |||
796 | duk_get_global_string(heap->ctx, THREAD_MAP("\xFF\xFFNETSURF_DUKTAPE_" "THREAD_MAP")); /* ... threads */ | |||
797 | duk_del_prop_index(heap->ctx, -1, thread->thread_idx); | |||
798 | duk_pop(heap->ctx); /* ... */ | |||
799 | ||||
800 | /* We can now free the thread object */ | |||
801 | free(thread); | |||
802 | ||||
803 | /* Finally give the heap a chance to clean up */ | |||
804 | duk_gc(heap->ctx, 0); | |||
805 | duk_gc(heap->ctx, DUK_GC_COMPACT(1U << 0)); | |||
806 | heap->live_threads--; | |||
807 | ||||
808 | /* And if the heap should now go, blow it away */ | |||
809 | if (heap->pending_destroy == true1 && heap->live_threads == 0) { | |||
810 | dukky_destroyheap(heap); | |||
811 | } | |||
812 | } | |||
813 | ||||
814 | /* exported interface documented in js.h */ | |||
815 | void js_destroythread(jsthread *thread) | |||
816 | { | |||
817 | thread->pending_destroy = true1; | |||
818 | if (thread->in_use == 0) { | |||
819 | dukky_destroythread(thread); | |||
820 | } | |||
821 | } | |||
822 | ||||
823 | static void dukky_enter_thread(jsthread *thread) | |||
824 | { | |||
825 | assert(thread != NULL)((thread != ((void*)0)) ? (void) (0) : __assert_fail ("thread != NULL" , "content/handlers/javascript/duktape/dukky.c", 825, __extension__ __PRETTY_FUNCTION__)); | |||
826 | thread->in_use++; | |||
827 | } | |||
828 | ||||
829 | static void dukky_leave_thread(jsthread *thread) | |||
830 | { | |||
831 | assert(thread != NULL)((thread != ((void*)0)) ? (void) (0) : __assert_fail ("thread != NULL" , "content/handlers/javascript/duktape/dukky.c", 831, __extension__ __PRETTY_FUNCTION__)); | |||
832 | assert(thread->in_use > 0)((thread->in_use > 0) ? (void) (0) : __assert_fail ("thread->in_use > 0" , "content/handlers/javascript/duktape/dukky.c", 832, __extension__ __PRETTY_FUNCTION__)); | |||
833 | ||||
834 | thread->in_use--; | |||
835 | if (thread->in_use == 0 && thread->pending_destroy == true1) { | |||
836 | dukky_destroythread(thread); | |||
837 | } | |||
838 | } | |||
839 | ||||
840 | duk_bool_t dukky_check_timeout(void *udata) | |||
841 | { | |||
842 | #define JS_EXEC_TIMEOUT_MS10000 10000 /* 10 seconds */ | |||
843 | jsheap *heap = (jsheap *) udata; | |||
844 | uint64_t now; | |||
845 | ||||
846 | (void) nsu_getmonotonic_ms(&now); | |||
847 | ||||
848 | /* This function may be called during duk heap construction, | |||
849 | * so only test for execution timeout if we've recorded a | |||
850 | * start time. | |||
851 | */ | |||
852 | return heap->exec_start_time != 0 && | |||
853 | now > (heap->exec_start_time + JS_EXEC_TIMEOUT_MS10000); | |||
854 | } | |||
855 | ||||
856 | static void dukky_dump_error(duk_context *ctx) | |||
857 | { | |||
858 | /* stack is ..., errobj */ | |||
859 | duk_dup_top(ctx); | |||
860 | /* ..., errobj, errobj */ | |||
861 | NSLOG(jserrors, WARNING, "Uncaught error in JS: %s", duk_safe_to_stacktrace(ctx, -1))do { if (NSLOG_LEVEL_WARNING >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_jserrors , NSLOG_LEVEL_WARNING, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 861, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s", duk_safe_to_stacktrace(ctx, -1) ); } } while(0); | |||
862 | /* ..., errobj, errobj.stackstring */ | |||
863 | duk_pop(ctx); | |||
864 | /* ..., errobj */ | |||
865 | } | |||
866 | ||||
867 | static void dukky_reset_start_time(duk_context *ctx) | |||
868 | { | |||
869 | duk_memory_functions funcs; | |||
870 | jsheap *heap; | |||
871 | duk_get_memory_functions(ctx, &funcs); | |||
872 | heap = funcs.udata; | |||
873 | (void) nsu_getmonotonic_ms(&heap->exec_start_time); | |||
874 | } | |||
875 | ||||
876 | duk_int_t dukky_pcall(duk_context *ctx, duk_size_t argc, bool_Bool reset_timeout) | |||
877 | { | |||
878 | if (reset_timeout) { | |||
879 | dukky_reset_start_time(ctx); | |||
880 | } | |||
881 | ||||
882 | duk_int_t ret = duk_pcall(ctx, argc); | |||
883 | if (ret) { | |||
884 | /* Something went wrong calling this... */ | |||
885 | dukky_dump_error(ctx); | |||
886 | } | |||
887 | ||||
888 | return ret; | |||
889 | } | |||
890 | ||||
891 | ||||
892 | void dukky_push_generics(duk_context *ctx, const char *generic) | |||
893 | { | |||
894 | /* ... */ | |||
895 | duk_get_global_string(ctx, GENERICS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "GENERICS_TABLE")); | |||
896 | /* ..., generics */ | |||
897 | duk_get_prop_string(ctx, -1, generic); | |||
898 | /* ..., generics, generic */ | |||
899 | duk_remove(ctx, -2); | |||
900 | /* ..., generic */ | |||
901 | } | |||
902 | ||||
903 | static duk_int_t dukky_push_context_dump(duk_context *ctx, void *udata) | |||
904 | { | |||
905 | duk_push_context_dump(ctx); | |||
906 | return 1; | |||
907 | } | |||
908 | ||||
909 | void dukky_log_stack_frame(duk_context *ctx, const char * reason) | |||
910 | { | |||
911 | if (duk_safe_call(ctx, dukky_push_context_dump, NULL((void*)0), 0, 1) != 0) { | |||
912 | duk_pop(ctx); | |||
913 | duk_push_string(ctx, "[???]"); | |||
914 | } | |||
915 | NSLOG(dukky, DEEPDEBUG, "%s, stack is: %s", reason, duk_safe_to_string(ctx, -1))do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 915, }; nslog__log(&_nslog_ctx , "%s, stack is: %s", reason, duk_safe_to_lstring((ctx), (-1) , ((void*)0))); } } while(0); | |||
916 | duk_pop(ctx); | |||
917 | } | |||
918 | ||||
919 | ||||
920 | /* exported interface documented in js.h */ | |||
921 | bool_Bool | |||
922 | js_exec(jsthread *thread, const uint8_t *txt, size_t txtlen, const char *name) | |||
923 | { | |||
924 | bool_Bool ret = false0; | |||
925 | assert(thread)((thread) ? (void) (0) : __assert_fail ("thread", "content/handlers/javascript/duktape/dukky.c" , 925, __extension__ __PRETTY_FUNCTION__)); | |||
926 | ||||
927 | if (txt == NULL((void*)0) || txtlen == 0) { | |||
928 | return false0; | |||
929 | } | |||
930 | ||||
931 | if (thread->pending_destroy) { | |||
932 | NSLOG(dukky, DEEPDEBUG, "Skipping exec call because thread is dead")do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 932, }; nslog__log(&_nslog_ctx , "Skipping exec call because thread is dead"); } } while(0); | |||
933 | return false0; | |||
934 | } | |||
935 | ||||
936 | dukky_enter_thread(thread); | |||
937 | ||||
938 | duk_set_top(CTX(thread->ctx), 0); | |||
939 | NSLOG(dukky, DEEPDEBUG, "Running %"PRIsizet" bytes from %s", txtlen, name)do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 939, }; nslog__log(&_nslog_ctx , "Running %""zu"" bytes from %s", txtlen, name); } } while(0 ); | |||
940 | /* NSLOG(dukky, DEEPDEBUG, "\n%s\n", txt); */ | |||
941 | ||||
942 | dukky_reset_start_time(CTX(thread->ctx)); | |||
943 | if (name != NULL((void*)0)) { | |||
944 | duk_push_string(CTX(thread->ctx), name); | |||
945 | } else { | |||
946 | duk_push_string(CTX(thread->ctx), "?unknown source?"); | |||
947 | } | |||
948 | if (duk_pcompile_lstring_filename(CTX,(duk_compile_raw(((thread->ctx)), (const char *)txt, txtlen , 1 | ((1U << 3)) | (1U << 7) | (1U << 9))) | |||
949 | DUK_COMPILE_EVAL,(duk_compile_raw(((thread->ctx)), (const char *)txt, txtlen , 1 | ((1U << 3)) | (1U << 7) | (1U << 9))) | |||
950 | (const char *)txt,(duk_compile_raw(((thread->ctx)), (const char *)txt, txtlen , 1 | ((1U << 3)) | (1U << 7) | (1U << 9))) | |||
951 | txtlen)(duk_compile_raw(((thread->ctx)), (const char *)txt, txtlen , 1 | ((1U << 3)) | (1U << 7) | (1U << 9))) != 0) { | |||
952 | NSLOG(dukky, DEBUG, "Failed to compile JavaScript input")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 952, }; nslog__log(&_nslog_ctx , "Failed to compile JavaScript input"); } } while(0); | |||
953 | goto handle_error; | |||
954 | } | |||
955 | ||||
956 | if (duk_pcall(CTX(thread->ctx), 0/*nargs*/) == DUK_EXEC_ERROR1) { | |||
957 | NSLOG(dukky, DEBUG, "Failed to execute JavaScript")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 957, }; nslog__log(&_nslog_ctx , "Failed to execute JavaScript"); } } while(0); | |||
958 | goto handle_error; | |||
959 | } | |||
960 | ||||
961 | if (duk_get_top(CTX(thread->ctx)) == 0) duk_push_boolean(CTX(thread->ctx), false0); | |||
962 | NSLOG(dukky, DEEPDEBUG, "Returning %s",do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 963, }; nslog__log(&_nslog_ctx , "Returning %s", duk_get_boolean((thread->ctx), 0) ? "true" : "false"); } } while(0) | |||
963 | duk_get_boolean(CTX, 0) ? "true" : "false")do { if (NSLOG_LEVEL_DEEPDEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEEPDEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 963, }; nslog__log(&_nslog_ctx , "Returning %s", duk_get_boolean((thread->ctx), 0) ? "true" : "false"); } } while(0); | |||
964 | ret = duk_get_boolean(CTX(thread->ctx), 0); | |||
965 | goto out; | |||
966 | ||||
967 | handle_error: | |||
968 | dukky_dump_error(CTX(thread->ctx)); | |||
969 | out: | |||
970 | dukky_leave_thread(thread); | |||
971 | return ret; | |||
972 | } | |||
973 | ||||
974 | static const char* dukky_event_proto(dom_event *evt) | |||
975 | { | |||
976 | const char *ret = PROTO_NAME(EVENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "EVENT"); | |||
977 | dom_string *type = NULL((void*)0); | |||
978 | dom_exception err; | |||
979 | ||||
980 | err = dom_event_get_type(evt, &type)_dom_event_get_type((dom_event *) (evt), (dom_string **) (& type)); | |||
981 | if (err != DOM_NO_ERR) { | |||
982 | goto out; | |||
983 | } | |||
984 | ||||
985 | if (dom_string_isequal(type, corestring_dom_keydown)) { | |||
986 | ret = PROTO_NAME(KEYBOARDEVENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "KEYBOARDEVENT"); | |||
987 | goto out; | |||
988 | } else if (dom_string_isequal(type, corestring_dom_keyup)) { | |||
989 | ret = PROTO_NAME(KEYBOARDEVENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "KEYBOARDEVENT"); | |||
990 | goto out; | |||
991 | } else if (dom_string_isequal(type, corestring_dom_keypress)) { | |||
992 | ret = PROTO_NAME(KEYBOARDEVENT)("\xFF\xFFNETSURF_DUKTAPE_" "PROTOTYPE_" "KEYBOARDEVENT"); | |||
993 | goto out; | |||
994 | } | |||
995 | ||||
996 | out: | |||
997 | if (type != NULL((void*)0)) { | |||
998 | dom_string_unref(type); | |||
999 | } | |||
1000 | ||||
1001 | return ret; | |||
1002 | } | |||
1003 | ||||
1004 | /*** New style event handling ***/ | |||
1005 | ||||
1006 | void dukky_push_event(duk_context *ctx, dom_event *evt) | |||
1007 | { | |||
1008 | /* ... */ | |||
1009 | duk_get_global_string(ctx, EVENT_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_MAP")); | |||
1010 | /* ... events */ | |||
1011 | duk_push_pointer(ctx, evt); | |||
1012 | /* ... events eventptr */ | |||
1013 | duk_get_prop(ctx, -2); | |||
1014 | /* ... events event? */ | |||
1015 | if (duk_is_undefined(ctx, -1)) { | |||
1016 | /* ... events undefined */ | |||
1017 | duk_pop(ctx); | |||
1018 | /* ... events */ | |||
1019 | duk_push_pointer(ctx, evt); | |||
1020 | if (dukky_create_object(ctx, dukky_event_proto(evt), 1) != DUK_EXEC_SUCCESS0) { | |||
1021 | /* ... events err */ | |||
1022 | duk_pop(ctx); | |||
1023 | /* ... events */ | |||
1024 | duk_push_object(ctx); | |||
1025 | /* ... events eobj[meh] */ | |||
1026 | } | |||
1027 | /* ... events eobj */ | |||
1028 | duk_push_pointer(ctx, evt); | |||
1029 | /* ... events eobj eventptr */ | |||
1030 | duk_dup(ctx, -2); | |||
1031 | /* ... events eobj eventptr eobj */ | |||
1032 | duk_put_prop(ctx, -4); | |||
1033 | /* ... events eobj */ | |||
1034 | } | |||
1035 | /* ... events event */ | |||
1036 | duk_replace(ctx, -2); | |||
1037 | /* ... event */ | |||
1038 | } | |||
1039 | ||||
1040 | static void dukky_push_handler_code_(duk_context *ctx, dom_string *name, | |||
1041 | dom_event_target *et) | |||
1042 | { | |||
1043 | dom_string *onname, *val; | |||
1044 | dom_element *ele = (dom_element *)et; | |||
1045 | dom_exception exc; | |||
1046 | dom_node_type ntype; | |||
1047 | ||||
1048 | /* If et is NULL, then we're actually dealing with the Window object | |||
1049 | * which has no default handlers and no way to assign handlers | |||
1050 | * which aren't directly stored in the HANDLER_MAGIC | |||
1051 | */ | |||
1052 | if (et == NULL((void*)0)) { | |||
1053 | duk_push_lstring(ctx, "", 0); | |||
1054 | return; | |||
1055 | } | |||
1056 | ||||
1057 | /* The rest of this assumes et is a proper event target and expands | |||
1058 | * out from there based on the assumption that all valid event targets | |||
1059 | * are nodes. | |||
1060 | */ | |||
1061 | exc = dom_node_get_node_type(et, &ntype)dom_node_get_node_type( (dom_node *) (et), (dom_node_type *) ( &ntype)); | |||
1062 | if (exc != DOM_NO_ERR) { | |||
1063 | duk_push_lstring(ctx, "", 0); | |||
1064 | return; | |||
1065 | } | |||
1066 | ||||
1067 | if (ntype != DOM_ELEMENT_NODE) { | |||
1068 | duk_push_lstring(ctx, "", 0); | |||
1069 | return; | |||
1070 | } | |||
1071 | ||||
1072 | exc = dom_string_concat(corestring_dom_on, name, &onname); | |||
1073 | if (exc != DOM_NO_ERR) { | |||
1074 | duk_push_lstring(ctx, "", 0); | |||
1075 | return; | |||
1076 | } | |||
1077 | ||||
1078 | exc = dom_element_get_attribute(ele, onname, &val)dom_element_get_attribute( (dom_element *) (ele), (onname), ( &val)); | |||
1079 | if ((exc != DOM_NO_ERR) || (val == NULL((void*)0))) { | |||
1080 | dom_string_unref(onname); | |||
1081 | duk_push_lstring(ctx, "", 0); | |||
1082 | return; | |||
1083 | } | |||
1084 | ||||
1085 | dom_string_unref(onname); | |||
1086 | duk_push_lstring(ctx, dom_string_data(val), dom_string_length(val)); | |||
1087 | dom_string_unref(val); | |||
1088 | } | |||
1089 | ||||
1090 | bool_Bool dukky_get_current_value_of_event_handler(duk_context *ctx, | |||
1091 | dom_string *name, | |||
1092 | dom_event_target *et) | |||
1093 | { | |||
1094 | /* Must be entered as: | |||
1095 | * ... node(et) | |||
1096 | */ | |||
1097 | duk_get_prop_string(ctx, -1, HANDLER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP")); | |||
1098 | /* ... node handlers */ | |||
1099 | duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name)); | |||
1100 | /* ... node handlers name */ | |||
1101 | duk_get_prop(ctx, -2); | |||
1102 | /* ... node handlers handler? */ | |||
1103 | if (duk_is_undefined(ctx, -1)) { | |||
1104 | /* ... node handlers undefined */ | |||
1105 | duk_pop_2(ctx); | |||
1106 | /* ... node */ | |||
1107 | dukky_push_handler_code_(ctx, name, et); | |||
1108 | /* ... node handlercode? */ | |||
1109 | /* TODO: If this is null, clean up and propagate */ | |||
1110 | /* ... node handlercode */ | |||
1111 | /** @todo This is entirely wrong, but it's hard to get right */ | |||
1112 | duk_push_string(ctx, "function (event) {"); | |||
1113 | /* ... node handlercode prefix */ | |||
1114 | duk_insert(ctx, -2); | |||
1115 | /* ... node prefix handlercode */ | |||
1116 | duk_push_string(ctx, "}"); | |||
1117 | /* ... node prefix handlercode suffix */ | |||
1118 | duk_concat(ctx, 3); | |||
1119 | /* ... node fullhandlersrc */ | |||
1120 | duk_push_string(ctx, "internal raw uncompiled handler"); | |||
1121 | /* ... node fullhandlersrc filename */ | |||
1122 | if (duk_pcompile(ctx, DUK_COMPILE_FUNCTION)(duk_compile_raw((ctx), ((void*)0), 0, 2 | ((1U << 4)) | (1U << 7))) != 0) { | |||
1123 | /* ... node err */ | |||
1124 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1125, }; nslog__log(&_nslog_ctx , "Unable to proceed with handler, could not compile"); } } while (0) | |||
1125 | "Unable to proceed with handler, could not compile")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1125, }; nslog__log(&_nslog_ctx , "Unable to proceed with handler, could not compile"); } } while (0); | |||
1126 | duk_pop_2(ctx); | |||
1127 | return false0; | |||
1128 | } | |||
1129 | /* ... node handler */ | |||
1130 | duk_insert(ctx, -2); | |||
1131 | /* ... handler node */ | |||
1132 | } else { | |||
1133 | /* ... node handlers handler */ | |||
1134 | duk_insert(ctx, -3); | |||
1135 | /* ... handler node handlers */ | |||
1136 | duk_pop(ctx); | |||
1137 | /* ... handler node */ | |||
1138 | } | |||
1139 | /* ... handler node */ | |||
1140 | return true1; | |||
1141 | } | |||
1142 | ||||
1143 | static void dukky_generic_event_handler(dom_event *evt, void *pw) | |||
1144 | { | |||
1145 | duk_context *ctx = (duk_context *)pw; | |||
1146 | dom_string *name; | |||
1147 | dom_exception exc; | |||
1148 | dom_event_target *targ; | |||
1149 | dom_event_flow_phase phase; | |||
1150 | duk_uarridx_t idx; | |||
1151 | event_listener_flags flags; | |||
1152 | ||||
1153 | NSLOG(dukky, DEBUG, "Handling an event in duktape interface...")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1153, }; nslog__log(&_nslog_ctx , "Handling an event in duktape interface..."); } } while(0); | |||
1154 | exc = dom_event_get_type(evt, &name)_dom_event_get_type((dom_event *) (evt), (dom_string **) (& name)); | |||
1155 | if (exc != DOM_NO_ERR) { | |||
1156 | NSLOG(dukky, DEBUG, "Unable to find the event name")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1156, }; nslog__log(&_nslog_ctx , "Unable to find the event name"); } } while(0); | |||
1157 | return; | |||
1158 | } | |||
1159 | NSLOG(dukky, DEBUG, "Event's name is %*s", (int)dom_string_length(name),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1160, }; nslog__log(&_nslog_ctx , "Event's name is %*s", (int)dom_string_length(name), dom_string_data (name)); } } while(0) | |||
1160 | dom_string_data(name))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1160, }; nslog__log(&_nslog_ctx , "Event's name is %*s", (int)dom_string_length(name), dom_string_data (name)); } } while(0); | |||
1161 | exc = dom_event_get_event_phase(evt, &phase)_dom_event_get_event_phase( (dom_event *) (evt), (dom_event_flow_phase *) (&phase)); | |||
1162 | if (exc != DOM_NO_ERR) { | |||
1163 | NSLOG(dukky, WARNING, "Unable to get event phase")do { if (NSLOG_LEVEL_WARNING >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_WARNING, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1163, }; nslog__log(&_nslog_ctx , "Unable to get event phase"); } } while(0); | |||
1164 | return; | |||
1165 | } | |||
1166 | NSLOG(dukky, DEBUG, "Event phase is: %s (%d)",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1168, }; nslog__log(&_nslog_ctx , "Event phase is: %s (%d)", phase == DOM_CAPTURING_PHASE ? "capturing" : phase == DOM_AT_TARGET ? "at-target" : phase == DOM_BUBBLING_PHASE ? "bubbling" : "unknown", (int)phase); } } while(0) | |||
1167 | phase == DOM_CAPTURING_PHASE ? "capturing" : phase == DOM_AT_TARGET ? "at-target" : phase == DOM_BUBBLING_PHASE ? "bubbling" : "unknown",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1168, }; nslog__log(&_nslog_ctx , "Event phase is: %s (%d)", phase == DOM_CAPTURING_PHASE ? "capturing" : phase == DOM_AT_TARGET ? "at-target" : phase == DOM_BUBBLING_PHASE ? "bubbling" : "unknown", (int)phase); } } while(0) | |||
1168 | (int)phase)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1168, }; nslog__log(&_nslog_ctx , "Event phase is: %s (%d)", phase == DOM_CAPTURING_PHASE ? "capturing" : phase == DOM_AT_TARGET ? "at-target" : phase == DOM_BUBBLING_PHASE ? "bubbling" : "unknown", (int)phase); } } while(0); | |||
1169 | ||||
1170 | exc = dom_event_get_current_target(evt, &targ)_dom_event_get_current_target( (dom_event *) (evt), (dom_event_target **) (&targ)); | |||
1171 | if (exc != DOM_NO_ERR) { | |||
1172 | dom_string_unref(name); | |||
1173 | NSLOG(dukky, DEBUG, "Unable to find the event target")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1173, }; nslog__log(&_nslog_ctx , "Unable to find the event target"); } } while(0); | |||
1174 | return; | |||
1175 | } | |||
1176 | ||||
1177 | /* If we're capturing right now, we skip the 'event handler' | |||
1178 | * and go straight to the extras | |||
1179 | */ | |||
1180 | if (phase == DOM_CAPTURING_PHASE) | |||
1181 | goto handle_extras; | |||
1182 | ||||
1183 | /* ... */ | |||
1184 | if (dukky_push_node(ctx, (dom_node *)targ) == false0) { | |||
1185 | dom_string_unref(name); | |||
1186 | dom_node_unref(targ)dom_node_unref((dom_node *) (targ)); | |||
1187 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1188, }; nslog__log(&_nslog_ctx , "Unable to push JS node representation?!"); } } while(0) | |||
1188 | "Unable to push JS node representation?!")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1188, }; nslog__log(&_nslog_ctx , "Unable to push JS node representation?!"); } } while(0); | |||
1189 | return; | |||
1190 | } | |||
1191 | /* ... node */ | |||
1192 | if (dukky_get_current_value_of_event_handler( | |||
1193 | ctx, name, (dom_event_target *)targ) == false0) { | |||
1194 | /* ... */ | |||
1195 | goto handle_extras; | |||
1196 | } | |||
1197 | /* ... handler node */ | |||
1198 | dukky_push_event(ctx, evt); | |||
1199 | /* ... handler node event */ | |||
1200 | dukky_reset_start_time(ctx); | |||
1201 | if (duk_pcall_method(ctx, 1) != 0) { | |||
1202 | /* Failed to run the method */ | |||
1203 | /* ... err */ | |||
1204 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1205, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a callback. Meh."); } } while(0 ) | |||
1205 | "OH NOES! An error running a callback. Meh.")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1205, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a callback. Meh."); } } while(0 ); | |||
1206 | exc = dom_event_stop_immediate_propagation(evt)_dom_event_stop_immediate_propagation((dom_event *) (evt)); | |||
1207 | if (exc != DOM_NO_ERR) | |||
1208 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1209, }; nslog__log(&_nslog_ctx , "WORSE! could not stop propagation"); } } while(0) | |||
1209 | "WORSE! could not stop propagation")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1209, }; nslog__log(&_nslog_ctx , "WORSE! could not stop propagation"); } } while(0); | |||
1210 | duk_get_prop_string(ctx, -1, "name"); | |||
1211 | duk_get_prop_string(ctx, -2, "message"); | |||
1212 | duk_get_prop_string(ctx, -3, "fileName"); | |||
1213 | duk_get_prop_string(ctx, -4, "lineNumber"); | |||
1214 | duk_get_prop_string(ctx, -5, "stack"); | |||
1215 | /* ... err name message fileName lineNumber stack */ | |||
1216 | NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1218, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0) | |||
1217 | duk_safe_to_string(ctx, -5),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1218, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0) | |||
1218 | duk_safe_to_string(ctx, -4))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1218, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0); | |||
1219 | NSLOG(dukky, INFO, " was at: %s line %s",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_INFO, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1221, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0) | |||
1220 | duk_safe_to_string(ctx, -3),do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_INFO, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1221, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0) | |||
1221 | duk_safe_to_string(ctx, -2))do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_INFO, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1221, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0); | |||
1222 | NSLOG(dukky, INFO, " Stack trace: %s",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_INFO, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1223, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring((ctx), (-1) , ((void*)0))); } } while(0) | |||
1223 | duk_safe_to_string(ctx, -1))do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_INFO, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1223, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring((ctx), (-1) , ((void*)0))); } } while(0); | |||
1224 | ||||
1225 | duk_pop_n(ctx, 6); | |||
1226 | /* ... */ | |||
1227 | goto handle_extras; | |||
1228 | } | |||
1229 | /* ... result */ | |||
1230 | if (duk_is_boolean(ctx, -1) && | |||
1231 | duk_to_boolean(ctx, -1) == 0) { | |||
1232 | dom_event_prevent_default(evt)_dom_event_prevent_default( (dom_event *) (evt)); | |||
1233 | } | |||
1234 | duk_pop(ctx); | |||
1235 | handle_extras: | |||
1236 | /* ... */ | |||
1237 | duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name)); | |||
1238 | dukky_push_node(ctx, (dom_node *)targ); | |||
1239 | /* ... type node */ | |||
1240 | if (dukky_event_target_push_listeners(ctx, true1)) { | |||
1241 | /* Nothing to do */ | |||
1242 | duk_pop(ctx); | |||
1243 | goto out; | |||
1244 | } | |||
1245 | /* ... sublisteners */ | |||
1246 | duk_push_array(ctx); | |||
1247 | /* ... sublisteners copy */ | |||
1248 | idx = 0; | |||
1249 | while (duk_get_prop_index(ctx, -2, idx)) { | |||
1250 | /* ... sublisteners copy handler */ | |||
1251 | duk_get_prop_index(ctx, -1, 1); | |||
1252 | /* ... sublisteners copy handler flags */ | |||
1253 | if ((event_listener_flags)duk_to_int(ctx, -1) & ELF_ONCE) { | |||
1254 | duk_dup(ctx, -4); | |||
1255 | /* ... subl copy handler flags subl */ | |||
1256 | dukky_shuffle_array(ctx, idx); | |||
1257 | duk_pop(ctx); | |||
1258 | /* ... subl copy handler flags */ | |||
1259 | } | |||
1260 | duk_pop(ctx); | |||
1261 | /* ... sublisteners copy handler */ | |||
1262 | duk_put_prop_index(ctx, -2, idx); | |||
1263 | /* ... sublisteners copy */ | |||
1264 | idx++; | |||
1265 | } | |||
1266 | /* ... sublisteners copy undefined */ | |||
1267 | duk_pop(ctx); | |||
1268 | /* ... sublisteners copy */ | |||
1269 | duk_insert(ctx, -2); | |||
1270 | /* ... copy sublisteners */ | |||
1271 | duk_pop(ctx); | |||
1272 | /* ... copy */ | |||
1273 | idx = 0; | |||
1274 | while (duk_get_prop_index(ctx, -1, idx++)) { | |||
1275 | /* ... copy handler */ | |||
1276 | if (duk_get_prop_index(ctx, -1, 2)) { | |||
1277 | /* ... copy handler meh */ | |||
1278 | duk_pop_2(ctx); | |||
1279 | continue; | |||
1280 | } | |||
1281 | duk_pop(ctx); | |||
1282 | duk_get_prop_index(ctx, -1, 0); | |||
1283 | duk_get_prop_index(ctx, -2, 1); | |||
1284 | /* ... copy handler callback flags */ | |||
1285 | flags = (event_listener_flags)duk_get_int(ctx, -1); | |||
1286 | duk_pop(ctx); | |||
1287 | /* ... copy handler callback */ | |||
1288 | if (((phase == DOM_CAPTURING_PHASE) && !(flags & ELF_CAPTURE)) || | |||
1289 | ((phase != DOM_CAPTURING_PHASE) && (flags & ELF_CAPTURE))) { | |||
1290 | duk_pop_2(ctx); | |||
1291 | /* ... copy */ | |||
1292 | continue; | |||
1293 | } | |||
1294 | /* ... copy handler callback */ | |||
1295 | dukky_push_node(ctx, (dom_node *)targ); | |||
1296 | /* ... copy handler callback node */ | |||
1297 | dukky_push_event(ctx, evt); | |||
1298 | /* ... copy handler callback node event */ | |||
1299 | dukky_reset_start_time(ctx); | |||
1300 | if (duk_pcall_method(ctx, 1) != 0) { | |||
1301 | /* Failed to run the method */ | |||
1302 | /* ... copy handler err */ | |||
1303 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1304, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a callback. Meh."); } } while(0 ) | |||
1304 | "OH NOES! An error running a callback. Meh.")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1304, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a callback. Meh."); } } while(0 ); | |||
1305 | exc = dom_event_stop_immediate_propagation(evt)_dom_event_stop_immediate_propagation((dom_event *) (evt)); | |||
1306 | if (exc != DOM_NO_ERR) | |||
1307 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1308, }; nslog__log(&_nslog_ctx , "WORSE! could not stop propagation"); } } while(0) | |||
1308 | "WORSE! could not stop propagation")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1308, }; nslog__log(&_nslog_ctx , "WORSE! could not stop propagation"); } } while(0); | |||
1309 | duk_get_prop_string(ctx, -1, "name"); | |||
1310 | duk_get_prop_string(ctx, -2, "message"); | |||
1311 | duk_get_prop_string(ctx, -3, "fileName"); | |||
1312 | duk_get_prop_string(ctx, -4, "lineNumber"); | |||
1313 | duk_get_prop_string(ctx, -5, "stack"); | |||
1314 | /* ... err name message fileName lineNumber stack */ | |||
1315 | NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1317, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0) | |||
1316 | duk_safe_to_string(ctx, -5),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1317, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0) | |||
1317 | duk_safe_to_string(ctx, -4))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1317, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring((ctx), ( -5), ((void*)0)), duk_safe_to_lstring((ctx), (-4), ((void*)0) )); } } while(0); | |||
1318 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1321, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0) | |||
1319 | " was at: %s line %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1321, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0) | |||
1320 | duk_safe_to_string(ctx, -3),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1321, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0) | |||
1321 | duk_safe_to_string(ctx, -2))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1321, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring((ctx ), (-3), ((void*)0)), duk_safe_to_lstring((ctx), (-2), ((void *)0))); } } while(0); | |||
1322 | NSLOG(dukky, DEBUG, " Stack trace: %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1323, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring((ctx), (-1) , ((void*)0))); } } while(0) | |||
1323 | duk_safe_to_string(ctx, -1))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1323, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring((ctx), (-1) , ((void*)0))); } } while(0); | |||
1324 | ||||
1325 | duk_pop_n(ctx, 7); | |||
1326 | /* ... copy */ | |||
1327 | continue; | |||
1328 | } | |||
1329 | /* ... copy handler result */ | |||
1330 | if (duk_is_boolean(ctx, -1) && | |||
1331 | duk_to_boolean(ctx, -1) == 0) { | |||
1332 | dom_event_prevent_default(evt)_dom_event_prevent_default( (dom_event *) (evt)); | |||
1333 | } | |||
1334 | duk_pop_2(ctx); | |||
1335 | /* ... copy */ | |||
1336 | } | |||
1337 | duk_pop_2(ctx); | |||
1338 | out: | |||
1339 | /* ... */ | |||
1340 | dom_node_unref(targ)dom_node_unref((dom_node *) (targ)); | |||
1341 | dom_string_unref(name); | |||
1342 | } | |||
1343 | ||||
1344 | void dukky_register_event_listener_for(duk_context *ctx, | |||
1345 | struct dom_element *ele, | |||
1346 | dom_string *name, | |||
1347 | bool_Bool capture) | |||
1348 | { | |||
1349 | dom_event_listener *listen = NULL((void*)0); | |||
1350 | dom_exception exc; | |||
1351 | ||||
1352 | /* ... */ | |||
1353 | if (ele == NULL((void*)0)) { | |||
1354 | /* A null element is the Window object */ | |||
1355 | duk_push_global_object(ctx); | |||
1356 | } else { | |||
1357 | /* Non null elements must be pushed as a node object */ | |||
1358 | if (dukky_push_node(ctx, (struct dom_node *)ele) == false0) | |||
1359 | return; | |||
1360 | } | |||
1361 | /* ... node */ | |||
1362 | duk_get_prop_string(ctx, -1, HANDLER_LISTENER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_LISTENER_MAP")); | |||
1363 | /* ... node handlers */ | |||
1364 | duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name)); | |||
1365 | /* ... node handlers name */ | |||
1366 | if (duk_has_prop(ctx, -2)) { | |||
1367 | /* ... node handlers */ | |||
1368 | duk_pop_2(ctx); | |||
1369 | /* ... */ | |||
1370 | return; | |||
1371 | } | |||
1372 | /* ... node handlers */ | |||
1373 | duk_push_lstring(ctx, dom_string_data(name), dom_string_length(name)); | |||
1374 | /* ... node handlers name */ | |||
1375 | duk_push_boolean(ctx, true1); | |||
1376 | /* ... node handlers name true */ | |||
1377 | duk_put_prop(ctx, -3); | |||
1378 | /* ... node handlers */ | |||
1379 | duk_pop_2(ctx); | |||
1380 | /* ... */ | |||
1381 | if (ele == NULL((void*)0)) { | |||
1382 | /* Nothing more to do, Window doesn't register in the | |||
1383 | * normal event listener flow | |||
1384 | */ | |||
1385 | return; | |||
1386 | } | |||
1387 | ||||
1388 | /* Otherwise add an event listener to the element */ | |||
1389 | exc = dom_event_listener_create(dukky_generic_event_handler, ctx, | |||
1390 | &listen); | |||
1391 | if (exc != DOM_NO_ERR) return; | |||
1392 | exc = dom_event_target_add_event_listener(dom_event_target_add_event_listener((dom_event_target *) (ele ), (dom_string *) (name), (struct dom_event_listener *) (listen ), (_Bool) (capture)) | |||
1393 | ele, name, listen, capture)dom_event_target_add_event_listener((dom_event_target *) (ele ), (dom_string *) (name), (struct dom_event_listener *) (listen ), (_Bool) (capture)); | |||
1394 | if (exc != DOM_NO_ERR) { | |||
1395 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1397, }; nslog__log(&_nslog_ctx , "Unable to register listener for %p.%*s", ele, (int)dom_string_length (name), dom_string_data(name)); } } while(0) | |||
1396 | "Unable to register listener for %p.%*s", ele,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1397, }; nslog__log(&_nslog_ctx , "Unable to register listener for %p.%*s", ele, (int)dom_string_length (name), dom_string_data(name)); } } while(0) | |||
1397 | (int)dom_string_length(name), dom_string_data(name))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1397, }; nslog__log(&_nslog_ctx , "Unable to register listener for %p.%*s", ele, (int)dom_string_length (name), dom_string_data(name)); } } while(0); | |||
1398 | } else { | |||
1399 | NSLOG(dukky, DEBUG, "have registered listener for %p.%*s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1400, }; nslog__log(&_nslog_ctx , "have registered listener for %p.%*s", ele, (int)dom_string_length (name), dom_string_data(name)); } } while(0) | |||
1400 | ele, (int)dom_string_length(name), dom_string_data(name))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1400, }; nslog__log(&_nslog_ctx , "have registered listener for %p.%*s", ele, (int)dom_string_length (name), dom_string_data(name)); } } while(0); | |||
1401 | } | |||
1402 | dom_event_listener_unref(listen); | |||
1403 | } | |||
1404 | ||||
1405 | /* The sub-listeners are a list of {callback,flags} tuples */ | |||
1406 | /* We return true if we created a new sublistener table */ | |||
1407 | /* If we're told to not create, but we want to, we still return true */ | |||
1408 | bool_Bool dukky_event_target_push_listeners(duk_context *ctx, bool_Bool dont_create) | |||
1409 | { | |||
1410 | bool_Bool ret = false0; | |||
1411 | /* ... type this */ | |||
1412 | duk_get_prop_string(ctx, -1, EVENT_LISTENER_JS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_LISTENER_JS_MAP")); | |||
1413 | if (duk_is_undefined(ctx, -1)) { | |||
1414 | /* ... type this null */ | |||
1415 | duk_pop(ctx); | |||
1416 | duk_push_object(ctx); | |||
1417 | duk_dup(ctx, -1); | |||
1418 | /* ... type this listeners listeners */ | |||
1419 | duk_put_prop_string(ctx, -3, EVENT_LISTENER_JS_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_LISTENER_JS_MAP")); | |||
1420 | /* ... type this listeners */ | |||
1421 | } | |||
1422 | /* ... type this listeners */ | |||
1423 | duk_insert(ctx, -3); | |||
1424 | /* ... listeners type this */ | |||
1425 | duk_pop(ctx); | |||
1426 | /* ... listeners type */ | |||
1427 | duk_dup(ctx, -1); | |||
1428 | /* ... listeners type type */ | |||
1429 | duk_get_prop(ctx, -3); | |||
1430 | /* ... listeners type ??? */ | |||
1431 | if (duk_is_undefined(ctx, -1)) { | |||
1432 | /* ... listeners type ??? */ | |||
1433 | if (dont_create == true1) { | |||
1434 | duk_pop_3(ctx); | |||
1435 | duk_push_undefined(ctx); | |||
1436 | return true1; | |||
1437 | } | |||
1438 | duk_pop(ctx); | |||
1439 | duk_push_array(ctx); | |||
1440 | duk_dup(ctx, -2); | |||
1441 | duk_dup(ctx, -2); | |||
1442 | /* ... listeners type sublisteners type sublisteners */ | |||
1443 | duk_put_prop(ctx, -5); | |||
1444 | /* ... listeners type sublisteners */ | |||
1445 | ret = true1; | |||
1446 | } | |||
1447 | duk_insert(ctx, -3); | |||
1448 | /* ... sublisteners listeners type */ | |||
1449 | duk_pop_2(ctx); | |||
1450 | /* ... sublisteners */ | |||
1451 | return ret; | |||
1452 | } | |||
1453 | ||||
1454 | /* Shuffle a duktape array "down" one. This involves iterating from | |||
1455 | * the index provided, shuffling elements down, until we reach an | |||
1456 | * undefined | |||
1457 | */ | |||
1458 | void dukky_shuffle_array(duk_context *ctx, duk_uarridx_t idx) | |||
1459 | { | |||
1460 | /* ... somearr */ | |||
1461 | while (duk_get_prop_index(ctx, -1, idx + 1)) { | |||
1462 | duk_put_prop_index(ctx, -2, idx); | |||
1463 | idx++; | |||
1464 | } | |||
1465 | /* ... somearr undefined */ | |||
1466 | duk_del_prop_index(ctx, -2, idx + 1); | |||
1467 | duk_pop(ctx); | |||
1468 | } | |||
1469 | ||||
1470 | ||||
1471 | void js_handle_new_element(jsthread *thread, struct dom_element *node) | |||
1472 | { | |||
1473 | assert(thread)((thread) ? (void) (0) : __assert_fail ("thread", "content/handlers/javascript/duktape/dukky.c" , 1473, __extension__ __PRETTY_FUNCTION__)); | |||
1474 | assert(node)((node) ? (void) (0) : __assert_fail ("node", "content/handlers/javascript/duktape/dukky.c" , 1474, __extension__ __PRETTY_FUNCTION__)); | |||
1475 | dom_namednodemap *map; | |||
1476 | dom_exception exc; | |||
1477 | dom_ulong idx; | |||
1478 | dom_ulong siz; | |||
1479 | dom_attr *attr = NULL((void*)0); | |||
1480 | dom_string *key = NULL((void*)0); | |||
1481 | dom_string *nodename; | |||
1482 | duk_bool_t is_body = false0; | |||
1483 | ||||
1484 | exc = dom_node_get_node_name(node, &nodename)dom_node_get_node_name((dom_node *) (node), (&nodename)); | |||
1485 | if (exc != DOM_NO_ERR) return; | |||
1486 | ||||
1487 | if (nodename == corestring_dom_BODY) | |||
1488 | is_body = true1; | |||
1489 | ||||
1490 | dom_string_unref(nodename); | |||
1491 | ||||
1492 | exc = dom_node_get_attributes(node, &map)dom_node_get_attributes( (dom_node *) (node), (struct dom_namednodemap **) (&map)); | |||
1493 | if (exc != DOM_NO_ERR) return; | |||
1494 | if (map == NULL((void*)0)) return; | |||
1495 | ||||
1496 | dukky_enter_thread(thread); | |||
1497 | ||||
1498 | exc = dom_namednodemap_get_length(map, &siz); | |||
1499 | if (exc != DOM_NO_ERR) goto out; | |||
1500 | ||||
1501 | for (idx = 0; idx < siz; idx++) { | |||
1502 | exc = dom_namednodemap_item(map, idx, &attr)_dom_namednodemap_item( (dom_namednodemap *) (map), (uint32_t ) (idx), (dom_node **) (&attr)); | |||
1503 | if (exc != DOM_NO_ERR) goto out; | |||
1504 | exc = dom_attr_get_name(attr, &key)dom_attr_get_name((struct dom_attr *) (attr), (&key)); | |||
1505 | if (exc != DOM_NO_ERR) goto out; | |||
1506 | if (is_body && ( | |||
1507 | key == corestring_dom_onblur || | |||
1508 | key == corestring_dom_onerror || | |||
1509 | key == corestring_dom_onfocus || | |||
1510 | key == corestring_dom_onload || | |||
1511 | key == corestring_dom_onresize || | |||
1512 | key == corestring_dom_onscroll)) { | |||
1513 | /* This is a forwarded event, it doesn't matter, | |||
1514 | * we should skip registering for it and later | |||
1515 | * we will register it for Window itself | |||
1516 | */ | |||
1517 | goto skip_register; | |||
1518 | } | |||
1519 | if (dom_string_length(key) > 2) { | |||
1520 | /* Can be on* */ | |||
1521 | const uint8_t *data = (const uint8_t *)dom_string_data(key); | |||
1522 | if (data[0] == 'o' && data[1] == 'n') { | |||
1523 | dom_string *sub = NULL((void*)0); | |||
1524 | exc = dom_string_substr( | |||
1525 | key, 2, dom_string_length(key), | |||
1526 | &sub); | |||
1527 | if (exc == DOM_NO_ERR) { | |||
1528 | dukky_register_event_listener_for( | |||
1529 | CTX(thread->ctx), node, sub, false0); | |||
1530 | dom_string_unref(sub); | |||
1531 | } | |||
1532 | } | |||
1533 | } | |||
1534 | skip_register: | |||
1535 | dom_string_unref(key); key = NULL((void*)0); | |||
1536 | dom_node_unref(attr)dom_node_unref((dom_node *) (attr)); attr = NULL((void*)0); | |||
1537 | } | |||
1538 | ||||
1539 | out: | |||
1540 | if (key != NULL((void*)0)) | |||
1541 | dom_string_unref(key); | |||
1542 | ||||
1543 | if (attr != NULL((void*)0)) | |||
1544 | dom_node_unref(attr)dom_node_unref((dom_node *) (attr)); | |||
1545 | ||||
1546 | dom_namednodemap_unref(map); | |||
1547 | ||||
1548 | dukky_leave_thread(thread); | |||
1549 | } | |||
1550 | ||||
1551 | void js_event_cleanup(jsthread *thread, struct dom_event *evt) | |||
1552 | { | |||
1553 | assert(thread)((thread) ? (void) (0) : __assert_fail ("thread", "content/handlers/javascript/duktape/dukky.c" , 1553, __extension__ __PRETTY_FUNCTION__)); | |||
1554 | dukky_enter_thread(thread); | |||
1555 | /* ... */ | |||
1556 | duk_get_global_string(CTX(thread->ctx), EVENT_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "EVENT_MAP")); | |||
1557 | /* ... EVENT_MAP */ | |||
1558 | duk_push_pointer(CTX(thread->ctx), evt); | |||
1559 | /* ... EVENT_MAP eventptr */ | |||
1560 | duk_del_prop(CTX(thread->ctx), -2); | |||
1561 | /* ... EVENT_MAP */ | |||
1562 | duk_pop(CTX(thread->ctx)); | |||
1563 | /* ... */ | |||
1564 | dukky_leave_thread(thread); | |||
1565 | } | |||
1566 | ||||
1567 | bool_Bool js_fire_event(jsthread *thread, const char *type, struct dom_document *doc, struct dom_node *target) | |||
1568 | { | |||
1569 | dom_exception exc; | |||
1570 | dom_event *evt; | |||
1571 | dom_event_target *body; | |||
1572 | ||||
1573 | NSLOG(dukky, DEBUG, "Event: %s (doc=%p, target=%p)", type, doc,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1574, }; nslog__log(&_nslog_ctx , "Event: %s (doc=%p, target=%p)", type, doc, target); } } while (0) | |||
| ||||
1574 | target)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1574, }; nslog__log(&_nslog_ctx , "Event: %s (doc=%p, target=%p)", type, doc, target); } } while (0); | |||
1575 | ||||
1576 | /** @todo Make this more generic, this only handles load and only | |||
1577 | * targetting the window, so that we actually stand a chance of | |||
1578 | * getting 3.4 out. | |||
1579 | */ | |||
1580 | ||||
1581 | if (target != NULL((void*)0)) | |||
1582 | /* Swallow non-Window-targetted events quietly */ | |||
1583 | return true1; | |||
1584 | ||||
1585 | if (strcmp(type, "load") != 0) | |||
1586 | /* Swallow non-load events quietly */ | |||
1587 | return true1; | |||
1588 | ||||
1589 | /* Okay, we're processing load, targetted at Window, do the single | |||
1590 | * thing which gets us there, which is to find the appropriate event | |||
1591 | * handler and call it. If we have no event handler on Window then | |||
1592 | * we divert to the body, and if there's no event handler there | |||
1593 | * we swallow the event silently | |||
1594 | */ | |||
1595 | ||||
1596 | exc = dom_event_create(&evt)_dom_event_create((dom_event **) (&evt)); | |||
1597 | if (exc != DOM_NO_ERR) return true1; | |||
1598 | exc = dom_event_init(evt, corestring_dom_load, false, false)_dom_event_init((dom_event *) (evt), (dom_string *) (corestring_dom_load ), (_Bool) (0), (_Bool) (0)); | |||
1599 | if (exc != DOM_NO_ERR) { | |||
1600 | dom_event_unref(evt)_dom_event_unref((dom_event *) (evt)); | |||
1601 | return true1; | |||
1602 | } | |||
1603 | dukky_enter_thread(thread); | |||
1604 | /* ... */ | |||
1605 | duk_get_global_string(CTX(thread->ctx), HANDLER_MAGIC("\xFF\xFFNETSURF_DUKTAPE_" "HANDLER_MAP")); | |||
1606 | /* ... handlers */ | |||
1607 | duk_push_lstring(CTX(thread->ctx), "load", 4); | |||
1608 | /* ... handlers "load" */ | |||
1609 | duk_get_prop(CTX(thread->ctx), -2); | |||
1610 | /* ... handlers handler? */ | |||
1611 | if (duk_is_undefined(CTX(thread->ctx), -1)) { | |||
1612 | /* No handler here, *try* and retrieve a handler from | |||
1613 | * the body | |||
1614 | */ | |||
1615 | duk_pop(CTX(thread->ctx)); | |||
1616 | /* ... handlers */ | |||
1617 | exc = dom_html_document_get_body(doc, &body)dom_html_document_get_body((dom_html_document *) (doc), (struct dom_html_element **) (&body)); | |||
1618 | if (exc != DOM_NO_ERR) { | |||
1619 | dom_event_unref(evt)_dom_event_unref((dom_event *) (evt)); | |||
1620 | dukky_leave_thread(thread); | |||
1621 | return true1; | |||
1622 | } | |||
1623 | dukky_push_node(CTX(thread->ctx), (struct dom_node *)body); | |||
1624 | /* ... handlers bodynode */ | |||
1625 | if (dukky_get_current_value_of_event_handler( | |||
1626 | CTX(thread->ctx), corestring_dom_load, body) == false0) { | |||
1627 | /* Unref the body, we don't need it any more */ | |||
1628 | dom_node_unref(body)dom_node_unref((dom_node *) (body)); | |||
1629 | /* ... handlers */ | |||
1630 | duk_pop(CTX(thread->ctx)); | |||
1631 | dukky_leave_thread(thread); | |||
1632 | return true1; | |||
1633 | } | |||
1634 | /* Unref the body, we don't need it any more */ | |||
1635 | dom_node_unref(body)dom_node_unref((dom_node *) (body)); | |||
1636 | /* ... handlers handler bodynode */ | |||
1637 | duk_pop(CTX(thread->ctx)); | |||
1638 | } | |||
1639 | /* ... handlers handler */ | |||
1640 | duk_insert(CTX(thread->ctx), -2); | |||
1641 | /* ... handler handlers */ | |||
1642 | duk_pop(CTX(thread->ctx)); | |||
1643 | /* ... handler */ | |||
1644 | duk_push_global_object(CTX(thread->ctx)); | |||
1645 | /* ... handler Window */ | |||
1646 | dukky_push_event(CTX(thread->ctx), evt); | |||
1647 | /* ... handler Window event */ | |||
1648 | dukky_reset_start_time(CTX(thread->ctx)); | |||
1649 | if (duk_pcall_method(CTX(thread->ctx), 1) != 0) { | |||
1650 | /* Failed to run the handler */ | |||
1651 | /* ... err */ | |||
1652 | NSLOG(dukky, DEBUG,do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1653, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a handler. Meh."); } } while(0) | |||
1653 | "OH NOES! An error running a handler. Meh.")do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1653, }; nslog__log(&_nslog_ctx , "OH NOES! An error running a handler. Meh."); } } while(0); | |||
1654 | duk_get_prop_string(CTX(thread->ctx), -1, "name"); | |||
1655 | duk_get_prop_string(CTX(thread->ctx), -2, "message"); | |||
1656 | duk_get_prop_string(CTX(thread->ctx), -3, "fileName"); | |||
1657 | duk_get_prop_string(CTX(thread->ctx), -4, "lineNumber"); | |||
1658 | duk_get_prop_string(CTX(thread->ctx), -5, "stack"); | |||
1659 | /* ... err name message fileName lineNumber stack */ | |||
1660 | NSLOG(dukky, DEBUG, "Uncaught error in JS: %s: %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1662, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring(((thread ->ctx)), (-5), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-4), ((void*)0))); } } while(0) | |||
1661 | duk_safe_to_string(CTX, -5),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1662, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring(((thread ->ctx)), (-5), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-4), ((void*)0))); } } while(0) | |||
1662 | duk_safe_to_string(CTX, -4))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1662, }; nslog__log(&_nslog_ctx , "Uncaught error in JS: %s: %s", duk_safe_to_lstring(((thread ->ctx)), (-5), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-4), ((void*)0))); } } while(0); | |||
1663 | NSLOG(dukky, DEBUG, " was at: %s line %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1665, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring(((thread ->ctx)), (-3), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-2), ((void*)0))); } } while(0) | |||
1664 | duk_safe_to_string(CTX, -3),do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1665, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring(((thread ->ctx)), (-3), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-2), ((void*)0))); } } while(0) | |||
1665 | duk_safe_to_string(CTX, -2))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1665, }; nslog__log(&_nslog_ctx , " was at: %s line %s", duk_safe_to_lstring(((thread ->ctx)), (-3), ((void*)0)), duk_safe_to_lstring(((thread-> ctx)), (-2), ((void*)0))); } } while(0); | |||
1666 | NSLOG(dukky, DEBUG, " Stack trace: %s",do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1667, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring(((thread-> ctx)), (-1), ((void*)0))); } } while(0) | |||
1667 | duk_safe_to_string(CTX, -1))do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_dukky , NSLOG_LEVEL_DEBUG, "content/handlers/javascript/duktape/dukky.c" , sizeof("content/handlers/javascript/duktape/dukky.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 1667, }; nslog__log(&_nslog_ctx , " Stack trace: %s", duk_safe_to_lstring(((thread-> ctx)), (-1), ((void*)0))); } } while(0); | |||
1668 | ||||
1669 | duk_pop_n(CTX(thread->ctx), 6); | |||
1670 | /* ... */ | |||
1671 | js_event_cleanup(thread, evt); | |||
1672 | dom_event_unref(evt)_dom_event_unref((dom_event *) (evt)); | |||
1673 | dukky_leave_thread(thread); | |||
1674 | return true1; | |||
1675 | } | |||
1676 | /* ... result */ | |||
1677 | duk_pop(CTX(thread->ctx)); | |||
1678 | /* ... */ | |||
1679 | js_event_cleanup(thread, evt); | |||
1680 | dom_event_unref(evt)_dom_event_unref((dom_event *) (evt)); | |||
1681 | dukky_leave_thread(thread); | |||
| ||||
1682 | return true1; | |||
1683 | } |