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