cosmopolitan/third_party/duktape/duk_bi_duktape.c

159 lines
4.9 KiB
C

/*
* Duktape built-ins
*
* Size optimization note: it might seem that vararg multipurpose functions
* like fin(), enc(), and dec() are not very size optimal, but using a single
* user-visible ECMAScript function saves a lot of run-time footprint; each
* Function instance takes >100 bytes. Using a shared native helper and a
* 'magic' value won't save much if there are multiple Function instances
* anyway.
*/
#include "third_party/duktape/duk_internal.h"
#if defined(DUK_USE_DUKTAPE_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {
duk_inspect_value(thr, -1);
return 1;
}
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {
duk_int_t level;
level = duk_to_int(thr, 0);
duk_inspect_callstack_entry(thr, level);
return 1;
}
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {
duk_small_uint_t flags;
flags = (duk_small_uint_t) duk_get_uint(thr, 0);
duk_heap_mark_and_sweep(thr->heap, flags);
/* XXX: Not sure what the best return value would be in the API.
* Return true for now.
*/
duk_push_true(thr);
return 1;
}
#if defined(DUK_USE_FINALIZER_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {
(void) duk_require_hobject(thr, 0);
if (duk_get_top(thr) >= 2) {
/* Set: currently a finalizer is disabled by setting it to
* undefined; this does not remove the property at the moment.
* The value could be type checked to be either a function
* or something else; if something else, the property could
* be deleted. Must use duk_set_finalizer() to keep
* DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.
*/
duk_set_top(thr, 2);
duk_set_finalizer(thr, 0);
return 0;
} else {
/* Get. */
DUK_ASSERT(duk_get_top(thr) == 1);
duk_get_finalizer(thr, 0);
return 1;
}
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {
duk_hstring *h_str;
/* Vararg function: must be careful to check/require arguments.
* The JSON helpers accept invalid indices and treat them like
* non-existent optional parameters.
*/
h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons. */
duk_require_valid_index(thr, 1);
if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
duk_set_top(thr, 2);
duk_hex_encode(thr, 1);
DUK_ASSERT_TOP(thr, 2);
} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
duk_set_top(thr, 2);
duk_base64_encode(thr, 1);
DUK_ASSERT_TOP(thr, 2);
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
duk_bi_json_stringify_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
3 /*idx_space*/,
DUK_JSON_FLAG_EXT_CUSTOM |
DUK_JSON_FLAG_ASCII_ONLY |
DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);
#endif
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
duk_bi_json_stringify_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
3 /*idx_space*/,
DUK_JSON_FLAG_EXT_COMPATIBLE |
DUK_JSON_FLAG_ASCII_ONLY /*flags*/);
#endif
} else {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
return 1;
}
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {
duk_hstring *h_str;
/* Vararg function: must be careful to check/require arguments.
* The JSON helpers accept invalid indices and treat them like
* non-existent optional parameters.
*/
h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons */
duk_require_valid_index(thr, 1);
if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
duk_set_top(thr, 2);
duk_hex_decode(thr, 1);
DUK_ASSERT_TOP(thr, 2);
} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
duk_set_top(thr, 2);
duk_base64_decode(thr, 1);
DUK_ASSERT_TOP(thr, 2);
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
duk_bi_json_parse_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);
#endif
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
duk_bi_json_parse_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);
#endif
} else {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
return 1;
}
/*
* Compact an object
*/
DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {
DUK_ASSERT_TOP(thr, 1);
duk_compact(thr, 0);
return 1; /* return the argument object */
}
#endif /* DUK_USE_DUKTAPE_BUILTIN */