]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.3.0/src-separate/duk_api_compile.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.3.0 / src-separate / duk_api_compile.c
1 /*
2 * Compilation and evaluation
3 */
4
5 #include "duk_internal.h"
6
7 typedef struct duk__compile_raw_args duk__compile_raw_args;
8 struct duk__compile_raw_args {
9 duk_size_t src_length; /* should be first on 64-bit platforms */
10 const duk_uint8_t *src_buffer;
11 duk_uint_t flags;
12 };
13
14 /* Eval is just a wrapper now. */
15 DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
16 duk_uint_t comp_flags;
17 duk_int_t rc;
18
19 DUK_ASSERT_CTX_VALID(ctx);
20
21 /* Note: strictness is *not* inherited from the current Duktape/C.
22 * This would be confusing because the current strictness state
23 * depends on whether we're running inside a Duktape/C activation
24 * (= strict mode) or outside of any activation (= non-strict mode).
25 * See tests/api/test-eval-strictness.c for more discussion.
26 */
27
28 /* [ ... source? filename ] (depends on flags) */
29
30 comp_flags = flags;
31 comp_flags |= DUK_COMPILE_EVAL;
32 rc = duk_compile_raw(ctx, src_buffer, src_length, comp_flags); /* may be safe, or non-safe depending on flags */
33
34 /* [ ... closure/error ] */
35
36 if (rc != DUK_EXEC_SUCCESS) {
37 rc = DUK_EXEC_ERROR;
38 goto got_rc;
39 }
40
41 duk_push_global_object(ctx); /* explicit 'this' binding, see GH-164 */
42
43 if (flags & DUK_COMPILE_SAFE) {
44 rc = duk_pcall_method(ctx, 0);
45 } else {
46 duk_call_method(ctx, 0);
47 rc = DUK_EXEC_SUCCESS;
48 }
49
50 /* [ ... result/error ] */
51
52 got_rc:
53 if (flags & DUK_COMPILE_NORESULT) {
54 duk_pop(ctx);
55 }
56
57 return rc;
58 }
59
60 /* Helper which can be called both directly and with duk_safe_call(). */
61 DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx) {
62 duk_hthread *thr = (duk_hthread *) ctx;
63 duk__compile_raw_args *comp_args;
64 duk_uint_t flags;
65 duk_small_uint_t comp_flags;
66 duk_hcompiledfunction *h_templ;
67
68 DUK_ASSERT_CTX_VALID(ctx);
69
70 /* Note: strictness is not inherited from the current Duktape/C
71 * context. Otherwise it would not be possible to compile
72 * non-strict code inside a Duktape/C activation (which is
73 * always strict now). See tests/api/test-eval-strictness.c
74 * for discussion.
75 */
76
77 /* [ ... source? filename &comp_args ] (depends on flags) */
78
79 comp_args = (duk__compile_raw_args *) duk_require_pointer(ctx, -1);
80 flags = comp_args->flags;
81 duk_pop(ctx);
82
83 /* [ ... source? filename ] */
84
85 if (!comp_args->src_buffer) {
86 duk_hstring *h_sourcecode;
87
88 h_sourcecode = duk_get_hstring(ctx, -2);
89 if ((flags & DUK_COMPILE_NOSOURCE) || /* args incorrect */
90 (h_sourcecode == NULL)) { /* e.g. duk_push_string_file_raw() pushed undefined */
91 /* XXX: when this error is caused by a nonexistent
92 * file given to duk_peval_file() or similar, the
93 * error message is not the best possible.
94 */
95 DUK_ERROR(thr, DUK_ERR_API_ERROR, DUK_STR_NO_SOURCECODE);
96 }
97 DUK_ASSERT(h_sourcecode != NULL);
98 comp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);
99 comp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode);
100 }
101 DUK_ASSERT(comp_args->src_buffer != NULL);
102
103 /* XXX: unnecessary translation of flags */
104 comp_flags = 0;
105 if (flags & DUK_COMPILE_EVAL) {
106 comp_flags |= DUK_JS_COMPILE_FLAG_EVAL;
107 }
108 if (flags & DUK_COMPILE_FUNCTION) {
109 comp_flags |= DUK_JS_COMPILE_FLAG_EVAL |
110 DUK_JS_COMPILE_FLAG_FUNCEXPR;
111 }
112 if (flags & DUK_COMPILE_STRICT) {
113 comp_flags |= DUK_JS_COMPILE_FLAG_STRICT;
114 }
115
116 /* [ ... source? filename ] */
117
118 duk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, comp_flags);
119
120 /* [ ... source? func_template ] */
121
122 if (flags & DUK_COMPILE_NOSOURCE) {
123 ;
124 } else {
125 duk_remove(ctx, -2);
126 }
127
128 /* [ ... func_template ] */
129
130 h_templ = (duk_hcompiledfunction *) duk_get_hobject(ctx, -1);
131 DUK_ASSERT(h_templ != NULL);
132 duk_js_push_closure(thr,
133 h_templ,
134 thr->builtins[DUK_BIDX_GLOBAL_ENV],
135 thr->builtins[DUK_BIDX_GLOBAL_ENV]);
136 duk_remove(ctx, -2); /* -> [ ... closure ] */
137
138 /* [ ... closure ] */
139
140 return 1;
141 }
142
143 DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
144 duk__compile_raw_args comp_args_alloc;
145 duk__compile_raw_args *comp_args = &comp_args_alloc;
146
147 DUK_ASSERT_CTX_VALID(ctx);
148
149 if ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {
150 /* String length is computed here to avoid multiple evaluation
151 * of a macro argument in the calling side.
152 */
153 src_length = DUK_STRLEN(src_buffer);
154 }
155
156 comp_args->src_buffer = (const duk_uint8_t *) src_buffer;
157 comp_args->src_length = src_length;
158 comp_args->flags = flags;
159 duk_push_pointer(ctx, (void *) comp_args);
160
161 /* [ ... source? filename &comp_args ] (depends on flags) */
162
163 if (flags & DUK_COMPILE_SAFE) {
164 duk_int_t rc;
165 duk_int_t nargs;
166 duk_int_t nrets = 1;
167
168 /* Arguments are either: [ filename &comp_args ] or [ source filename &comp_args ] */
169 nargs = (flags & DUK_COMPILE_NOSOURCE) ? 2 : 3;
170 rc = duk_safe_call(ctx, duk__do_compile, nargs, nrets);
171
172 /* [ ... closure ] */
173 return rc;
174 }
175
176 (void) duk__do_compile(ctx);
177
178 /* [ ... closure ] */
179 return DUK_EXEC_SUCCESS;
180 }