/* * 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 "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 */