| /* |
| * Variable access |
| */ |
| |
| #include "duk_internal.h" |
| |
| DUK_EXTERNAL void duk_get_var(duk_context *ctx) { |
| duk_hthread *thr = (duk_hthread *) ctx; |
| duk_activation *act; |
| duk_hstring *h_varname; |
| duk_small_int_t throw_flag = 1; /* always throw ReferenceError for unresolvable */ |
| |
| DUK_ASSERT_CTX_VALID(ctx); |
| |
| h_varname = duk_require_hstring(ctx, -1); /* XXX: tostring? */ |
| DUK_ASSERT(h_varname != NULL); |
| |
| act = duk_hthread_get_current_activation(thr); |
| if (act) { |
| (void) duk_js_getvar_activation(thr, act, h_varname, throw_flag); /* -> [ ... varname val this ] */ |
| } else { |
| /* Outside any activation -> look up from global. */ |
| DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL); |
| (void) duk_js_getvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, throw_flag); |
| } |
| |
| /* [ ... varname val this ] (because throw_flag == 1, always resolved) */ |
| |
| duk_pop(ctx); |
| duk_remove(ctx, -2); |
| |
| /* [ ... val ] */ |
| |
| /* Return value would be pointless: because throw_flag==1, we always |
| * throw if the identifier doesn't resolve. |
| */ |
| return; |
| } |
| |
| DUK_EXTERNAL void duk_put_var(duk_context *ctx) { |
| duk_hthread *thr = (duk_hthread *) ctx; |
| duk_activation *act; |
| duk_hstring *h_varname; |
| duk_tval *tv_val; |
| duk_small_int_t throw_flag; |
| |
| DUK_ASSERT_CTX_VALID(ctx); |
| |
| h_varname = duk_require_hstring(ctx, -2); /* XXX: tostring? */ |
| DUK_ASSERT(h_varname != NULL); |
| |
| tv_val = duk_require_tval(ctx, -1); |
| |
| throw_flag = duk_is_strict_call(ctx); |
| |
| act = duk_hthread_get_current_activation(thr); |
| if (act) { |
| duk_js_putvar_activation(thr, act, h_varname, tv_val, throw_flag); /* -> [ ... varname val this ] */ |
| } else { |
| /* Outside any activation -> put to global. */ |
| DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL); |
| duk_js_putvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, tv_val, throw_flag); |
| } |
| |
| /* [ ... varname val ] */ |
| |
| duk_pop_2(ctx); |
| |
| /* [ ... ] */ |
| |
| return; |
| } |
| |
| DUK_EXTERNAL duk_bool_t duk_del_var(duk_context *ctx) { |
| DUK_ASSERT_CTX_VALID(ctx); |
| |
| DUK_ERROR_UNIMPLEMENTED_DEFMSG((duk_hthread *) ctx); |
| return 0; |
| } |
| |
| DUK_EXTERNAL duk_bool_t duk_has_var(duk_context *ctx) { |
| DUK_ASSERT_CTX_VALID(ctx); |
| |
| DUK_ERROR_UNIMPLEMENTED_DEFMSG((duk_hthread *) ctx); |
| return 0; |
| } |