2 * Compilation and evaluation
5 #include "duk_internal.h"
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
;
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
;
19 DUK_ASSERT_CTX_VALID(ctx
);
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.
28 /* [ ... source? filename ] (depends on 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 */
34 /* [ ... closure/error ] */
36 if (rc
!= DUK_EXEC_SUCCESS
) {
41 duk_push_global_object(ctx
); /* explicit 'this' binding, see GH-164 */
43 if (flags
& DUK_COMPILE_SAFE
) {
44 rc
= duk_pcall_method(ctx
, 0);
46 duk_call_method(ctx
, 0);
47 rc
= DUK_EXEC_SUCCESS
;
50 /* [ ... result/error ] */
53 if (flags
& DUK_COMPILE_NORESULT
) {
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
;
65 duk_small_uint_t comp_flags
;
66 duk_hcompiledfunction
*h_templ
;
68 DUK_ASSERT_CTX_VALID(ctx
);
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
77 /* [ ... source? filename &comp_args ] (depends on flags) */
79 comp_args
= (duk__compile_raw_args
*) duk_require_pointer(ctx
, -1);
80 flags
= comp_args
->flags
;
83 /* [ ... source? filename ] */
85 if (!comp_args
->src_buffer
) {
86 duk_hstring
*h_sourcecode
;
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.
95 DUK_ERROR(thr
, DUK_ERR_API_ERROR
, DUK_STR_NO_SOURCECODE
);
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
);
101 DUK_ASSERT(comp_args
->src_buffer
!= NULL
);
103 /* XXX: unnecessary translation of flags */
105 if (flags
& DUK_COMPILE_EVAL
) {
106 comp_flags
|= DUK_JS_COMPILE_FLAG_EVAL
;
108 if (flags
& DUK_COMPILE_FUNCTION
) {
109 comp_flags
|= DUK_JS_COMPILE_FLAG_EVAL
|
110 DUK_JS_COMPILE_FLAG_FUNCEXPR
;
112 if (flags
& DUK_COMPILE_STRICT
) {
113 comp_flags
|= DUK_JS_COMPILE_FLAG_STRICT
;
116 /* [ ... source? filename ] */
118 duk_js_compile(thr
, comp_args
->src_buffer
, comp_args
->src_length
, comp_flags
);
120 /* [ ... source? func_template ] */
122 if (flags
& DUK_COMPILE_NOSOURCE
) {
128 /* [ ... func_template ] */
130 h_templ
= (duk_hcompiledfunction
*) duk_get_hobject(ctx
, -1);
131 DUK_ASSERT(h_templ
!= NULL
);
132 duk_js_push_closure(thr
,
134 thr
->builtins
[DUK_BIDX_GLOBAL_ENV
],
135 thr
->builtins
[DUK_BIDX_GLOBAL_ENV
]);
136 duk_remove(ctx
, -2); /* -> [ ... closure ] */
138 /* [ ... closure ] */
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
;
147 DUK_ASSERT_CTX_VALID(ctx
);
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.
153 src_length
= DUK_STRLEN(src_buffer
);
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
);
161 /* [ ... source? filename &comp_args ] (depends on flags) */
163 if (flags
& DUK_COMPILE_SAFE
) {
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
);
172 /* [ ... closure ] */
176 (void) duk__do_compile(ctx
);
178 /* [ ... closure ] */
179 return DUK_EXEC_SUCCESS
;