]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_bi_duktape.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / prometheus-cpp / 3rdparty / civetweb / src / third_party / duktape-1.5.2 / src-separate / duk_bi_duktape.c
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 /* Raw helper to extract internal information / statistics about a value.
15 * The return values are version specific and must not expose anything
16 * that would lead to security issues (e.g. exposing compiled function
17 * 'data' buffer might be an issue). Currently only counts and sizes and
18 * such are given so there should not be a security impact.
19 */
20 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) {
21 duk_hthread *thr = (duk_hthread *) ctx;
22 duk_tval *tv;
23 duk_heaphdr *h;
24 duk_int_t i, n;
25
26 DUK_UNREF(thr);
27
28 /* result array */
29 duk_push_array(ctx); /* -> [ val arr ] */
30
31 /* type tag (public) */
32 duk_push_int(ctx, duk_get_type(ctx, 0));
33
34 /* address */
35 tv = duk_get_tval(ctx, 0);
36 DUK_ASSERT(tv != NULL); /* because arg count is 1 */
37 if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
38 h = DUK_TVAL_GET_HEAPHDR(tv);
39 duk_push_pointer(ctx, (void *) h);
40 } else {
41 /* internal type tag */
42 duk_push_int(ctx, (duk_int_t) DUK_TVAL_GET_TAG(tv));
43 goto done;
44 }
45 DUK_ASSERT(h != NULL);
46
47 /* refcount */
48 #ifdef DUK_USE_REFERENCE_COUNTING
49 duk_push_size_t(ctx, DUK_HEAPHDR_GET_REFCOUNT(h));
50 #else
51 duk_push_undefined(ctx);
52 #endif
53
54 /* heaphdr size and additional allocation size, followed by
55 * type specific stuff (with varying value count)
56 */
57 switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {
58 case DUK_HTYPE_STRING: {
59 duk_hstring *h_str = (duk_hstring *) h;
60 duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1));
61 break;
62 }
63 case DUK_HTYPE_OBJECT: {
64 duk_hobject *h_obj = (duk_hobject *) h;
65 duk_small_uint_t hdr_size;
66 if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h_obj)) {
67 hdr_size = (duk_small_uint_t) sizeof(duk_hcompiledfunction);
68 } else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h_obj)) {
69 hdr_size = (duk_small_uint_t) sizeof(duk_hnativefunction);
70 } else if (DUK_HOBJECT_IS_THREAD(h_obj)) {
71 hdr_size = (duk_small_uint_t) sizeof(duk_hthread);
72 #if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
73 } else if (DUK_HOBJECT_IS_BUFFEROBJECT(h_obj)) {
74 hdr_size = (duk_small_uint_t) sizeof(duk_hbufferobject);
75 #endif
76 } else {
77 hdr_size = (duk_small_uint_t) sizeof(duk_hobject);
78 }
79 duk_push_uint(ctx, (duk_uint_t) hdr_size);
80 duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj));
81 duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj));
82 /* Note: e_next indicates the number of gc-reachable entries
83 * in the entry part, and also indicates the index where the
84 * next new property would be inserted. It does *not* indicate
85 * the number of non-NULL keys present in the object. That
86 * value could be counted separately but requires a pass through
87 * the key list.
88 */
89 duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj));
90 duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));
91 duk_push_uint(ctx, (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));
92 if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h_obj)) {
93 duk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, (duk_hcompiledfunction *) h_obj);
94 if (h_data) {
95 duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_data));
96 } else {
97 duk_push_uint(ctx, 0);
98 }
99 }
100 break;
101 }
102 case DUK_HTYPE_BUFFER: {
103 duk_hbuffer *h_buf = (duk_hbuffer *) h;
104 if (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {
105 if (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {
106 duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_external)));
107 } else {
108 /* When alloc_size == 0 the second allocation may not
109 * actually exist.
110 */
111 duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_dynamic)));
112 }
113 duk_push_uint(ctx, (duk_uint_t) (DUK_HBUFFER_GET_SIZE(h_buf)));
114 } else {
115 duk_push_uint(ctx, (duk_uint_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf) + 1));
116 }
117 break;
118
119 }
120 }
121
122 done:
123 /* set values into ret array */
124 /* XXX: primitive to make array from valstack slice */
125 n = duk_get_top(ctx);
126 for (i = 2; i < n; i++) {
127 duk_dup(ctx, i);
128 duk_put_prop_index(ctx, 1, i - 2);
129 }
130 duk_dup(ctx, 1);
131 return 1;
132 }
133
134 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx) {
135 duk_hthread *thr = (duk_hthread *) ctx;
136 duk_activation *act;
137 duk_uint_fast32_t pc;
138 duk_uint_fast32_t line;
139 duk_int_t level;
140
141 /* -1 = top callstack entry, callstack[callstack_top - 1]
142 * -callstack_top = bottom callstack entry, callstack[0]
143 */
144 level = duk_to_int(ctx, 0);
145 if (level >= 0 || -level > (duk_int_t) thr->callstack_top) {
146 return 0;
147 }
148 DUK_ASSERT(level >= -((duk_int_t) thr->callstack_top) && level <= -1);
149 act = thr->callstack + thr->callstack_top + level;
150
151 duk_push_object(ctx);
152
153 duk_push_tval(ctx, &act->tv_func);
154
155 /* Relevant PC is just before current one because PC is
156 * post-incremented. This should match what error augment
157 * code does.
158 */
159 pc = duk_hthread_get_act_prev_pc(thr, act);
160 duk_push_uint(ctx, (duk_uint_t) pc);
161
162 #if defined(DUK_USE_PC2LINE)
163 line = duk_hobject_pc2line_query(ctx, -2, pc);
164 #else
165 line = 0;
166 #endif
167 duk_push_uint(ctx, (duk_uint_t) line);
168
169 /* Providing access to e.g. act->lex_env would be dangerous: these
170 * internal structures must never be accessible to the application.
171 * Duktape relies on them having consistent data, and this consistency
172 * is only asserted for, not checked for.
173 */
174
175 /* [ level obj func pc line ] */
176
177 /* XXX: version specific array format instead? */
178 duk_xdef_prop_stridx_wec(ctx, -4, DUK_STRIDX_LINE_NUMBER);
179 duk_xdef_prop_stridx_wec(ctx, -3, DUK_STRIDX_PC);
180 duk_xdef_prop_stridx_wec(ctx, -2, DUK_STRIDX_LC_FUNCTION);
181 return 1;
182 }
183
184 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx) {
185 #ifdef DUK_USE_MARK_AND_SWEEP
186 duk_hthread *thr = (duk_hthread *) ctx;
187 duk_small_uint_t flags;
188 duk_bool_t rc;
189
190 flags = (duk_small_uint_t) duk_get_uint(ctx, 0);
191 rc = duk_heap_mark_and_sweep(thr->heap, flags);
192
193 /* XXX: Not sure what the best return value would be in the API.
194 * Return a boolean for now. Note that rc == 0 is success (true).
195 */
196 duk_push_boolean(ctx, !rc);
197 return 1;
198 #else
199 DUK_UNREF(ctx);
200 return 0;
201 #endif
202 }
203
204 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx) {
205 (void) duk_require_hobject(ctx, 0);
206 if (duk_get_top(ctx) >= 2) {
207 /* Set: currently a finalizer is disabled by setting it to
208 * undefined; this does not remove the property at the moment.
209 * The value could be type checked to be either a function
210 * or something else; if something else, the property could
211 * be deleted.
212 */
213 duk_set_top(ctx, 2);
214 (void) duk_put_prop_stridx(ctx, 0, DUK_STRIDX_INT_FINALIZER);
215 return 0;
216 } else {
217 /* Get. */
218 DUK_ASSERT(duk_get_top(ctx) == 1);
219 duk_get_prop_stridx(ctx, 0, DUK_STRIDX_INT_FINALIZER);
220 return 1;
221 }
222 }
223
224 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx) {
225 duk_hthread *thr = (duk_hthread *) ctx;
226 duk_hstring *h_str;
227
228 DUK_UNREF(thr);
229
230 /* Vararg function: must be careful to check/require arguments.
231 * The JSON helpers accept invalid indices and treat them like
232 * non-existent optional parameters.
233 */
234
235 h_str = duk_require_hstring(ctx, 0);
236 duk_require_valid_index(ctx, 1);
237
238 if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
239 duk_set_top(ctx, 2);
240 duk_hex_encode(ctx, 1);
241 DUK_ASSERT_TOP(ctx, 2);
242 } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
243 duk_set_top(ctx, 2);
244 duk_base64_encode(ctx, 1);
245 DUK_ASSERT_TOP(ctx, 2);
246 #ifdef DUK_USE_JX
247 } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
248 duk_bi_json_stringify_helper(ctx,
249 1 /*idx_value*/,
250 2 /*idx_replacer*/,
251 3 /*idx_space*/,
252 DUK_JSON_FLAG_EXT_CUSTOM |
253 DUK_JSON_FLAG_ASCII_ONLY |
254 DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);
255 #endif
256 #ifdef DUK_USE_JC
257 } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
258 duk_bi_json_stringify_helper(ctx,
259 1 /*idx_value*/,
260 2 /*idx_replacer*/,
261 3 /*idx_space*/,
262 DUK_JSON_FLAG_EXT_COMPATIBLE |
263 DUK_JSON_FLAG_ASCII_ONLY /*flags*/);
264 #endif
265 } else {
266 return DUK_RET_TYPE_ERROR;
267 }
268 return 1;
269 }
270
271 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx) {
272 duk_hthread *thr = (duk_hthread *) ctx;
273 duk_hstring *h_str;
274
275 DUK_UNREF(thr);
276
277 /* Vararg function: must be careful to check/require arguments.
278 * The JSON helpers accept invalid indices and treat them like
279 * non-existent optional parameters.
280 */
281
282 h_str = duk_require_hstring(ctx, 0);
283 duk_require_valid_index(ctx, 1);
284
285 if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
286 duk_set_top(ctx, 2);
287 duk_hex_decode(ctx, 1);
288 DUK_ASSERT_TOP(ctx, 2);
289 } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
290 duk_set_top(ctx, 2);
291 duk_base64_decode(ctx, 1);
292 DUK_ASSERT_TOP(ctx, 2);
293 #ifdef DUK_USE_JX
294 } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
295 duk_bi_json_parse_helper(ctx,
296 1 /*idx_value*/,
297 2 /*idx_replacer*/,
298 DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);
299 #endif
300 #ifdef DUK_USE_JC
301 } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
302 duk_bi_json_parse_helper(ctx,
303 1 /*idx_value*/,
304 2 /*idx_replacer*/,
305 DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);
306 #endif
307 } else {
308 return DUK_RET_TYPE_ERROR;
309 }
310 return 1;
311 }
312
313 /*
314 * Compact an object
315 */
316
317 DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx) {
318 DUK_ASSERT_TOP(ctx, 1);
319 duk_compact(ctx, 0);
320 return 1; /* return the argument object */
321 }