159 lines
4.9 KiB
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 */
|