1 /*
2 * Duktape built-ins
3 *
4 * Size optimization note: it might seem that vararg multipurpose functions
5 * like fin(), enc(), and dec() are not very size optimal, but using a single
6 * user-visible ECMAScript function saves a lot of run-time footprint; each
7 * Function instance takes >100 bytes. Using a shared native helper and a
8 * 'magic' value won't save much if there are multiple Function instances
9 * anyway.
10 */
11
12 #include "duk_internal.h"
13
14 #if defined(DUK_USE_DUKTAPE_BUILTIN)
15
duk_bi_duktape_object_info(duk_hthread * thr)16 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {
17 duk_inspect_value(thr, -1);
18 return 1;
19 }
20
duk_bi_duktape_object_act(duk_hthread * thr)21 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {
22 duk_int_t level;
23
24 level = duk_to_int(thr, 0);
25 duk_inspect_callstack_entry(thr, level);
26 return 1;
27 }
28
duk_bi_duktape_object_gc(duk_hthread * thr)29 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {
30 duk_small_uint_t flags;
31
32 flags = (duk_small_uint_t) duk_get_uint(thr, 0);
33 duk_heap_mark_and_sweep(thr->heap, flags);
34
35 /* XXX: Not sure what the best return value would be in the API.
36 * Return true for now.
37 */
38 duk_push_true(thr);
39 return 1;
40 }
41
42 #if defined(DUK_USE_FINALIZER_SUPPORT)
duk_bi_duktape_object_fin(duk_hthread * thr)43 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {
44 (void) duk_require_hobject(thr, 0);
45 if (duk_get_top(thr) >= 2) {
46 /* Set: currently a finalizer is disabled by setting it to
47 * undefined; this does not remove the property at the moment.
48 * The value could be type checked to be either a function
49 * or something else; if something else, the property could
50 * be deleted. Must use duk_set_finalizer() to keep
51 * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.
52 */
53 duk_set_top(thr, 2);
54 duk_set_finalizer(thr, 0);
55 return 0;
56 } else {
57 /* Get. */
58 DUK_ASSERT(duk_get_top(thr) == 1);
59 duk_get_finalizer(thr, 0);
60 return 1;
61 }
62 }
63 #endif /* DUK_USE_FINALIZER_SUPPORT */
64
duk_bi_duktape_object_enc(duk_hthread * thr)65 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {
66 duk_hstring *h_str;
67
68 /* Vararg function: must be careful to check/require arguments.
69 * The JSON helpers accept invalid indices and treat them like
70 * non-existent optional parameters.
71 */
72
73 h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons. */
74 duk_require_valid_index(thr, 1);
75
76 if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
77 duk_set_top(thr, 2);
78 duk_hex_encode(thr, 1);
79 DUK_ASSERT_TOP(thr, 2);
80 } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
81 duk_set_top(thr, 2);
82 duk_base64_encode(thr, 1);
83 DUK_ASSERT_TOP(thr, 2);
84 #if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
85 } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
86 duk_bi_json_stringify_helper(thr,
87 1 /*idx_value*/,
88 2 /*idx_replacer*/,
89 3 /*idx_space*/,
90 DUK_JSON_FLAG_EXT_CUSTOM |
91 DUK_JSON_FLAG_ASCII_ONLY |
92 DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);
93 #endif
94 #if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
95 } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
96 duk_bi_json_stringify_helper(thr,
97 1 /*idx_value*/,
98 2 /*idx_replacer*/,
99 3 /*idx_space*/,
100 DUK_JSON_FLAG_EXT_COMPATIBLE |
101 DUK_JSON_FLAG_ASCII_ONLY /*flags*/);
102 #endif
103 } else {
104 DUK_DCERROR_TYPE_INVALID_ARGS(thr);
105 }
106 return 1;
107 }
108
duk_bi_duktape_object_dec(duk_hthread * thr)109 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {
110 duk_hstring *h_str;
111
112 /* Vararg function: must be careful to check/require arguments.
113 * The JSON helpers accept invalid indices and treat them like
114 * non-existent optional parameters.
115 */
116
117 h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons */
118 duk_require_valid_index(thr, 1);
119
120 if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
121 duk_set_top(thr, 2);
122 duk_hex_decode(thr, 1);
123 DUK_ASSERT_TOP(thr, 2);
124 } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
125 duk_set_top(thr, 2);
126 duk_base64_decode(thr, 1);
127 DUK_ASSERT_TOP(thr, 2);
128 #if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
129 } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
130 duk_bi_json_parse_helper(thr,
131 1 /*idx_value*/,
132 2 /*idx_replacer*/,
133 DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);
134 #endif
135 #if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
136 } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
137 duk_bi_json_parse_helper(thr,
138 1 /*idx_value*/,
139 2 /*idx_replacer*/,
140 DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);
141 #endif
142 } else {
143 DUK_DCERROR_TYPE_INVALID_ARGS(thr);
144 }
145 return 1;
146 }
147
148 /*
149 * Compact an object
150 */
151
duk_bi_duktape_object_compact(duk_hthread * thr)152 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {
153 DUK_ASSERT_TOP(thr, 1);
154 duk_compact(thr, 0);
155 return 1; /* return the argument object */
156 }
157
158 #endif /* DUK_USE_DUKTAPE_BUILTIN */
159