28#include <nsutils/time.h>
40#include "duktape/binding.h"
41#include "duktape/generics.js.inc"
42#include "duktape/polyfill.js.inc"
49#define EVENT_MAGIC MAGIC(EVENT_MAP)
50#define HANDLER_LISTENER_MAGIC MAGIC(HANDLER_LISTENER_MAP)
51#define HANDLER_MAGIC MAGIC(HANDLER_MAP)
52#define EVENT_LISTENER_JS_MAGIC MAGIC(EVENT_LISTENER_JS_MAP)
53#define GENERICS_MAGIC MAGIC(GENERICS_TABLE)
54#define THREAD_MAP MAGIC(THREAD_MAP)
92 "Unable to find dukky prototype for `%s` - falling back to HTMLUnknownElement",
111 NSLOG(dukky, DEEPDEBUG,
"Call the init function");
119 NSLOG(dukky, DEEPDEBUG,
"name=%s nargs=%d", name + 2, args);
140 NSLOG(dukky, DEEPDEBUG,
"created");
180 NSLOG(dukky, ERROR,
"Failed to populate object prototype");
199 NSLOG(dukky, DEEPDEBUG,
"Created: %s", what);
205#define SET_HTML_CLASS(CLASS) \
206 *html_class = PROTO_NAME(HTML##CLASS##ELEMENT); \
208 SLEN(PROTO_NAME(HTML)) + \
213 const char **html_class,
size_t *html_class_len)
216 case DOM_HTML_ELEMENT_TYPE_HTML:
219 case DOM_HTML_ELEMENT_TYPE_HEAD:
222 case DOM_HTML_ELEMENT_TYPE_META:
225 case DOM_HTML_ELEMENT_TYPE_BASE:
228 case DOM_HTML_ELEMENT_TYPE_TITLE:
231 case DOM_HTML_ELEMENT_TYPE_BODY:
234 case DOM_HTML_ELEMENT_TYPE_DIV:
237 case DOM_HTML_ELEMENT_TYPE_FORM:
240 case DOM_HTML_ELEMENT_TYPE_LINK:
243 case DOM_HTML_ELEMENT_TYPE_BUTTON:
246 case DOM_HTML_ELEMENT_TYPE_INPUT:
249 case DOM_HTML_ELEMENT_TYPE_TEXTAREA:
252 case DOM_HTML_ELEMENT_TYPE_OPTGROUP:
255 case DOM_HTML_ELEMENT_TYPE_OPTION:
258 case DOM_HTML_ELEMENT_TYPE_SELECT:
261 case DOM_HTML_ELEMENT_TYPE_HR:
264 case DOM_HTML_ELEMENT_TYPE_DL:
267 case DOM_HTML_ELEMENT_TYPE_DIR:
270 case DOM_HTML_ELEMENT_TYPE_MENU:
273 case DOM_HTML_ELEMENT_TYPE_FIELDSET:
276 case DOM_HTML_ELEMENT_TYPE_LEGEND:
279 case DOM_HTML_ELEMENT_TYPE_P:
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:
290 case DOM_HTML_ELEMENT_TYPE_BLOCKQUOTE:
291 case DOM_HTML_ELEMENT_TYPE_Q:
294 case DOM_HTML_ELEMENT_TYPE_PRE:
297 case DOM_HTML_ELEMENT_TYPE_BR:
300 case DOM_HTML_ELEMENT_TYPE_LABEL:
303 case DOM_HTML_ELEMENT_TYPE_UL:
306 case DOM_HTML_ELEMENT_TYPE_OL:
309 case DOM_HTML_ELEMENT_TYPE_LI:
312 case DOM_HTML_ELEMENT_TYPE_FONT:
315 case DOM_HTML_ELEMENT_TYPE_DEL:
316 case DOM_HTML_ELEMENT_TYPE_INS:
319 case DOM_HTML_ELEMENT_TYPE_A:
322 case DOM_HTML_ELEMENT_TYPE_BASEFONT:
325 case DOM_HTML_ELEMENT_TYPE_IMG:
328 case DOM_HTML_ELEMENT_TYPE_OBJECT:
331 case DOM_HTML_ELEMENT_TYPE_PARAM:
334 case DOM_HTML_ELEMENT_TYPE_APPLET:
337 case DOM_HTML_ELEMENT_TYPE_MAP:
340 case DOM_HTML_ELEMENT_TYPE_AREA:
343 case DOM_HTML_ELEMENT_TYPE_SCRIPT:
346 case DOM_HTML_ELEMENT_TYPE_CAPTION:
349 case DOM_HTML_ELEMENT_TYPE_TD:
350 case DOM_HTML_ELEMENT_TYPE_TH:
353 case DOM_HTML_ELEMENT_TYPE_COL:
354 case DOM_HTML_ELEMENT_TYPE_COLGROUP:
357 case DOM_HTML_ELEMENT_TYPE_THEAD:
358 case DOM_HTML_ELEMENT_TYPE_TBODY:
359 case DOM_HTML_ELEMENT_TYPE_TFOOT:
362 case DOM_HTML_ELEMENT_TYPE_TABLE:
365 case DOM_HTML_ELEMENT_TYPE_TR:
368 case DOM_HTML_ELEMENT_TYPE_STYLE:
371 case DOM_HTML_ELEMENT_TYPE_FRAMESET:
374 case DOM_HTML_ELEMENT_TYPE_FRAME:
377 case DOM_HTML_ELEMENT_TYPE_IFRAME:
380 case DOM_HTML_ELEMENT_TYPE_ISINDEX:
383 case DOM_HTML_ELEMENT_TYPE_CANVAS:
386 case DOM_HTML_ELEMENT_TYPE__COUNT:
387 assert(
type != DOM_HTML_ELEMENT_TYPE__COUNT);
389 case DOM_HTML_ELEMENT_TYPE__UNKNOWN:
394 *html_class = PROTO_NAME(HTMLELEMENT);
396 SLEN(PROTO_NAME(HTML)) +
408 dom_node_type nodetype;
411 err = dom_node_get_node_type(node, &nodetype);
412 if (err != DOM_NO_ERR) {
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);
425 if (err != DOM_NO_ERR) {
428 "dom_node_get_namespace() failed");
432 if (
namespace == NULL) {
434 NSLOG(dukky, DEBUG,
"no namespace");
439 if (dom_string_isequal(
namespace, corestring_dom_html_namespace) ==
false) {
442 dom_string_unref(
namespace);
445 dom_string_unref(
namespace);
447 err = dom_html_element_get_tag_type(node, &
type);
448 if (err != DOM_NO_ERR) {
449 type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
453 &html_class, &html_class_len);
461 case DOM_COMMENT_NODE:
464 case DOM_DOCUMENT_NODE:
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:
484 NSLOG(dukky, DEEPDEBUG,
"Pushing node %p", node);
502 NSLOG(dukky, DEEPDEBUG,
"Found it memoised: %s", what);
558 if (ptr == NULL && size == 0)
566 return realloc(ptr, size);
601 jsheap *ret = calloc(1,
sizeof(*ret));
603 NSLOG(dukky, DEBUG,
"Creating new duktape javascript heap");
618 dukky_create_prototypes(ctx);
632 NSLOG(dukky, DEBUG,
"Destroying duktape javascript context");
647#define CTX (ret->ctx)
653 assert(heap != NULL);
656 ret = calloc(1,
sizeof (*ret));
658 NSLOG(dukky, ERROR,
"Unable to allocate new JS thread structure");
663 "New javascript/duktape thread, win_priv=%p, doc_priv=%p",
703 (
const char *)polyfill_js, polyfill_js_len) != 0) {
705 NSLOG(dukky, CRITICAL,
"Unable to compile polyfill.js, thread aborted");
711 NSLOG(dukky, CRITICAL,
"Unable to run polyfill.js, thread aborted");
724 (
const char *)generics_js, generics_js_len) != 0) {
726 NSLOG(dukky, CRITICAL,
"Unable to compile generics.js, thread aborted");
732 NSLOG(dukky, CRITICAL,
"Unable to run generics.js, thread aborted");
750 NSLOG(dukky, DEBUG,
"New thread is %p in heap %p", thread, heap);
758#define CTX (thread->ctx)
770 NSLOG(dukky, DEBUG,
"Closing down extant thread %p in heap %p", thread, thread->
heap);
787 assert(thread->
in_use == 0);
791 NSLOG(dukky, DEBUG,
"Closing down extant thread %p in heap %p", thread, heap);
818 if (thread->
in_use == 0) {
825 assert(thread != NULL);
831 assert(thread != NULL);
832 assert(thread->
in_use > 0);
842#define JS_EXEC_TIMEOUT_MS 10000
846 (void) nsu_getmonotonic_ms(&now);
927 if (txt == NULL || txtlen == 0) {
932 NSLOG(dukky, DEEPDEBUG,
"Skipping exec call because thread is dead");
939 NSLOG(dukky, DEEPDEBUG,
"Running %"PRIsizet" bytes from %s", txtlen, name);
952 NSLOG(dukky, DEBUG,
"Failed to compile JavaScript input");
957 NSLOG(dukky, DEBUG,
"Failed to execute JavaScript");
962 NSLOG(dukky, DEEPDEBUG,
"Returning %s",
976 const char *ret = PROTO_NAME(EVENT);
977 dom_string *
type = NULL;
980 err = dom_event_get_type(evt, &
type);
981 if (err != DOM_NO_ERR) {
985 if (dom_string_isequal(
type, corestring_dom_keydown)) {
986 ret = PROTO_NAME(KEYBOARDEVENT);
988 }
else if (dom_string_isequal(
type, corestring_dom_keyup)) {
989 ret = PROTO_NAME(KEYBOARDEVENT);
991 }
else if (dom_string_isequal(
type, corestring_dom_keypress)) {
992 ret = PROTO_NAME(KEYBOARDEVENT);
998 dom_string_unref(
type);
1041 dom_event_target *et)
1043 dom_string *onname, *val;
1044 dom_element *ele = (dom_element *)et;
1046 dom_node_type ntype;
1061 exc = dom_node_get_node_type(et, &ntype);
1062 if (exc != DOM_NO_ERR) {
1067 if (ntype != DOM_ELEMENT_NODE) {
1072 exc = dom_string_concat(corestring_dom_on, name, &onname);
1073 if (exc != DOM_NO_ERR) {
1078 exc = dom_element_get_attribute(ele, onname, &val);
1079 if ((exc != DOM_NO_ERR) || (val == NULL)) {
1080 dom_string_unref(onname);
1085 dom_string_unref(onname);
1087 dom_string_unref(val);
1092 dom_event_target *et)
1125 "Unable to proceed with handler, could not compile");
1148 dom_event_target *targ;
1149 dom_event_flow_phase phase;
1153 NSLOG(dukky, DEBUG,
"Handling an event in duktape interface...");
1154 exc = dom_event_get_type(evt, &name);
1155 if (exc != DOM_NO_ERR) {
1156 NSLOG(dukky, DEBUG,
"Unable to find the event name");
1159 NSLOG(dukky, DEBUG,
"Event's name is %*s", (
int)dom_string_length(name),
1160 dom_string_data(name));
1161 exc = dom_event_get_event_phase(evt, &phase);
1162 if (exc != DOM_NO_ERR) {
1163 NSLOG(dukky, WARNING,
"Unable to get event phase");
1166 NSLOG(dukky, DEBUG,
"Event phase is: %s (%d)",
1167 phase == DOM_CAPTURING_PHASE ?
"capturing" : phase == DOM_AT_TARGET ?
"at-target" : phase == DOM_BUBBLING_PHASE ?
"bubbling" :
"unknown",
1170 exc = dom_event_get_current_target(evt, &targ);
1171 if (exc != DOM_NO_ERR) {
1172 dom_string_unref(name);
1173 NSLOG(dukky, DEBUG,
"Unable to find the event target");
1180 if (phase == DOM_CAPTURING_PHASE)
1185 dom_string_unref(name);
1186 dom_node_unref(targ);
1188 "Unable to push JS node representation?!");
1193 ctx, name, (dom_event_target *)targ) ==
false) {
1205 "OH NOES! An error running a callback. Meh.");
1206 exc = dom_event_stop_immediate_propagation(evt);
1207 if (exc != DOM_NO_ERR)
1209 "WORSE! could not stop propagation");
1216 NSLOG(dukky, DEBUG,
"Uncaught error in JS: %s: %s",
1219 NSLOG(dukky, INFO,
" was at: %s line %s",
1222 NSLOG(dukky, INFO,
" Stack trace: %s",
1232 dom_event_prevent_default(evt);
1288 if (((phase == DOM_CAPTURING_PHASE) && !(flags &
ELF_CAPTURE)) ||
1289 ((phase != DOM_CAPTURING_PHASE) && (flags &
ELF_CAPTURE))) {
1304 "OH NOES! An error running a callback. Meh.");
1305 exc = dom_event_stop_immediate_propagation(evt);
1306 if (exc != DOM_NO_ERR)
1308 "WORSE! could not stop propagation");
1315 NSLOG(dukky, DEBUG,
"Uncaught error in JS: %s: %s",
1319 " was at: %s line %s",
1322 NSLOG(dukky, DEBUG,
" Stack trace: %s",
1332 dom_event_prevent_default(evt);
1340 dom_node_unref(targ);
1341 dom_string_unref(name);
1345 struct dom_element *ele,
1349 dom_event_listener *listen = NULL;
1391 if (exc != DOM_NO_ERR)
return;
1392 exc = dom_event_target_add_event_listener(
1393 ele, name, listen, capture);
1394 if (exc != DOM_NO_ERR) {
1396 "Unable to register listener for %p.%*s", ele,
1397 (
int)dom_string_length(name), dom_string_data(name));
1399 NSLOG(dukky, DEBUG,
"have registered listener for %p.%*s",
1400 ele, (
int)dom_string_length(name), dom_string_data(name));
1402 dom_event_listener_unref(listen);
1433 if (dont_create ==
true) {
1475 dom_namednodemap *map;
1479 dom_attr *attr = NULL;
1480 dom_string *key = NULL;
1481 dom_string *nodename;
1484 exc = dom_node_get_node_name(node, &nodename);
1485 if (exc != DOM_NO_ERR)
return;
1487 if (nodename == corestring_dom_BODY)
1490 dom_string_unref(nodename);
1492 exc = dom_node_get_attributes(node, &map);
1493 if (exc != DOM_NO_ERR)
return;
1494 if (map == NULL)
return;
1498 exc = dom_namednodemap_get_length(map, &siz);
1499 if (exc != DOM_NO_ERR)
goto out;
1501 for (idx = 0; idx < siz; idx++) {
1502 exc = dom_namednodemap_item(map, idx, &attr);
1503 if (exc != DOM_NO_ERR)
goto out;
1504 exc = dom_attr_get_name(attr, &key);
1505 if (exc != DOM_NO_ERR)
goto out;
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)) {
1519 if (dom_string_length(key) > 2) {
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;
1524 exc = dom_string_substr(
1525 key, 2, dom_string_length(key),
1527 if (exc == DOM_NO_ERR) {
1529 CTX, node, sub,
false);
1530 dom_string_unref(sub);
1535 dom_string_unref(key); key = NULL;
1536 dom_node_unref(attr); attr = NULL;
1541 dom_string_unref(key);
1544 dom_node_unref(attr);
1546 dom_namednodemap_unref(map);
1571 dom_event_target *body;
1573 NSLOG(dukky, DEBUG,
"Event: %s (doc=%p, target=%p)",
type, doc,
1585 if (strcmp(
type,
"load") != 0)
1596 exc = dom_event_create(&evt);
1597 if (exc != DOM_NO_ERR)
return true;
1598 exc = dom_event_init(evt, corestring_dom_load,
false,
false);
1599 if (exc != DOM_NO_ERR) {
1600 dom_event_unref(evt);
1617 exc = dom_html_document_get_body(doc, &body);
1618 if (exc != DOM_NO_ERR) {
1619 dom_event_unref(evt);
1626 CTX, corestring_dom_load, body) ==
false) {
1628 dom_node_unref(body);
1635 dom_node_unref(body);
1653 "OH NOES! An error running a handler. Meh.");
1660 NSLOG(dukky, DEBUG,
"Uncaught error in JS: %s: %s",
1663 NSLOG(dukky, DEBUG,
" was at: %s line %s",
1666 NSLOG(dukky, DEBUG,
" Stack trace: %s",
1672 dom_event_unref(evt);
1680 dom_event_unref(evt);
Content handling interface.
nserror javascript_init(void)
Useful interned string pointers (interface).
duk_small_int_t duk_ret_t
duk_small_uint_t duk_bool_t
duk_int_fast32_t duk_int_t
void js_destroythread(jsthread *thread)
Destroy a javascript thread.
void dukky_push_generics(duk_context *ctx, const char *generic)
static void dukky_destroythread(jsthread *thread)
Destroy a Duktape thread.
static void dukky_dump_error(duk_context *ctx)
void js_destroyheap(jsheap *heap)
Destroy a previously created heap.
void dukky_shuffle_array(duk_context *ctx, duk_uarridx_t idx)
#define HANDLER_LISTENER_MAGIC
void js_handle_new_element(jsthread *thread, struct dom_element *node)
Handle a new element being created.
void dukky_inject_not_ctr(duk_context *ctx, int idx, const char *name)
static void dukky_enter_thread(jsthread *thread)
static void dukky_leave_thread(jsthread *thread)
void js_event_cleanup(jsthread *thread, struct dom_event *evt)
Handle an event propagation finished callback.
void js_finalise(void)
finalise javascript interpreter
void dukky_push_event(duk_context *ctx, dom_event *evt)
nserror js_newheap(int timeout, jsheap **heap)
Create a new javascript heap.
static void dukky_html_element_class_from_tag_type(dom_html_element_type type, const char **html_class, size_t *html_class_len)
bool dukky_get_current_value_of_event_handler(duk_context *ctx, dom_string *name, dom_event_target *et)
static void * dukky_realloc_function(void *udata, void *ptr, duk_size_t size)
static void dukky_generic_event_handler(dom_event *evt, void *pw)
duk_int_t dukky_pcall(duk_context *ctx, duk_size_t argc, bool reset_timeout)
nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread **thread)
Create a new javascript thread.
duk_bool_t dukky_push_node_stacked(duk_context *ctx)
static void dukky_push_handler_code_(duk_context *ctx, dom_string *name, dom_event_target *et)
static void dukky_destroyheap(jsheap *heap)
void dukky_log_stack_frame(duk_context *ctx, const char *reason)
static void dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
duk_bool_t dukky_push_node(duk_context *ctx, struct dom_node *node)
duk_bool_t dukky_check_timeout(void *udata)
#define EVENT_LISTENER_JS_MAGIC
void js_initialise(void)
Initialise javascript interpreter.
bool js_fire_event(jsthread *thread, const char *type, struct dom_document *doc, struct dom_node *target)
fire an event at a dom node
static void dukky_reset_start_time(duk_context *ctx)
static duk_int_t dukky_push_context_dump(duk_context *ctx, void *udata)
#define SET_HTML_CLASS(CLASS)
duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args)
static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
static void * dukky_alloc_function(void *udata, duk_size_t size)
static duk_ret_t dukky_bad_constructor(duk_context *ctx)
static const char * dukky_event_proto(dom_event *evt)
void dukky_register_event_listener_for(duk_context *ctx, struct dom_element *ele, dom_string *name, bool capture)
#define JS_EXEC_TIMEOUT_MS
static void dukky_free_function(void *udata, void *ptr)
bool dukky_event_target_push_listeners(duk_context *ctx, bool dont_create)
bool js_exec(jsthread *thread, const uint8_t *txt, size_t txtlen, const char *name)
execute some javascript in a context
nserror js_closethread(jsthread *thread)
Close a javascript thread.
Duktapeish implementation of javascript engine functions, prototypes.
DUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx)
DUK_EXTERNAL const char * duk_get_string(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_set_global_object(duk_hthread *thr)
DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx)
DUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx)
DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_pop_3(duk_hthread *thr)
DUK_EXTERNAL void duk_push_global_object(duk_hthread *thr)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr)
DUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags)
DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key)
DUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets)
DUK_EXTERNAL void duk_push_null(duk_hthread *thr)
DUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs)
DUK_EXTERNAL const char * duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len)
DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr)
DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx)
DUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs)
DUK_EXTERNAL void duk_dup_top(duk_hthread *thr)
DUK_EXTERNAL duk_hthread * duk_require_context(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val)
DUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs)
DUK_EXTERNAL void duk_pop(duk_hthread *thr)
DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr)
DUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key)
DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL duk_hthread * duk_create_heap(duk_alloc_function alloc_func, duk_realloc_function realloc_func, duk_free_function free_func, void *heap_udata, duk_fatal_function fatal_handler)
DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key)
DUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs)
DUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx)
DUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs)
DUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val)
DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key)
DUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val)
DUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr)
DUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr)
DUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx)
DUK_EXTERNAL void duk_pop_2(duk_hthread *thr)
DUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count)
DUK_EXTERNAL void duk_push_undefined(duk_hthread *thr)
DUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx)
DUK_EXTERNAL const char * duk_push_string(duk_hthread *thr, const char *str)
DUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx)
DUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx)
DUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count)
DUK_EXTERNAL const char * duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx)
DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx)
DUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key)
DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx)
#define duk_push_thread(ctx)
#define DUK_COMPILE_FUNCTION
#define duk_pcompile(ctx, flags)
#define duk_pcompile_lstring_filename(ctx, flags, buf, len)
#define duk_safe_to_string(ctx, idx)
nserror
Enumeration of error codes.
@ NSERROR_INIT_FAILED
Initialisation failed.
@ NSERROR_NOMEM
Memory exhaustion.
Netsurf additional integer type formatting macros.
#define PRIsizet
c99 standard printf formatting for size_t type
Interface to javascript engine functions.
#define NSLOG(catname, level, logmsg, args...)
#define NSLOG_COMPILED_MIN_LEVEL
duk_uarridx_t next_thread
monotonic thread counter
duk_context * ctx
duktape base context
bool pending_destroy
Whether this heap is pending destruction.
unsigned int live_threads
number of live threads
duk_context * ctx
The duktape thread context.
jsheap * heap
The heap this thread belongs to.
bool pending_destroy
Whether this thread is pending destruction.
duk_uarridx_t thread_idx
The thread number.
unsigned int in_use
The number of times this thread is in use.
Option reading and saving interface.
Interface to a number of general purpose functionality.
#define fallthrough
switch fall through
#define SLEN(x)
Calculate length of constant C string.