1 /*
2  *  Variable access
3  */
4 
5 #include "duk_internal.h"
6 
duk_get_var(duk_context * ctx)7 DUK_EXTERNAL void duk_get_var(duk_context *ctx) {
8 	duk_hthread *thr = (duk_hthread *) ctx;
9 	duk_activation *act;
10 	duk_hstring *h_varname;
11 	duk_small_int_t throw_flag = 1;  /* always throw ReferenceError for unresolvable */
12 
13 	DUK_ASSERT_CTX_VALID(ctx);
14 
15 	h_varname = duk_require_hstring(ctx, -1);  /* XXX: tostring? */
16 	DUK_ASSERT(h_varname != NULL);
17 
18 	act = duk_hthread_get_current_activation(thr);
19 	if (act) {
20 		(void) duk_js_getvar_activation(thr, act, h_varname, throw_flag);  /* -> [ ... varname val this ] */
21 	} else {
22 		/* Outside any activation -> look up from global. */
23 		DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);
24 		(void) duk_js_getvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, throw_flag);
25 	}
26 
27 	/* [ ... varname val this ]  (because throw_flag == 1, always resolved) */
28 
29 	duk_pop(ctx);
30 	duk_remove(ctx, -2);
31 
32 	/* [ ... val ] */
33 
34 	/* Return value would be pointless: because throw_flag==1, we always
35 	 * throw if the identifier doesn't resolve.
36 	 */
37 	return;
38 }
39 
duk_put_var(duk_context * ctx)40 DUK_EXTERNAL void duk_put_var(duk_context *ctx) {
41 	duk_hthread *thr = (duk_hthread *) ctx;
42 	duk_activation *act;
43 	duk_hstring *h_varname;
44 	duk_tval *tv_val;
45 	duk_small_int_t throw_flag;
46 
47 	DUK_ASSERT_CTX_VALID(ctx);
48 
49 	h_varname = duk_require_hstring(ctx, -2);  /* XXX: tostring? */
50 	DUK_ASSERT(h_varname != NULL);
51 
52 	tv_val = duk_require_tval(ctx, -1);
53 
54 	throw_flag = duk_is_strict_call(ctx);
55 
56 	act = duk_hthread_get_current_activation(thr);
57 	if (act) {
58 		duk_js_putvar_activation(thr, act, h_varname, tv_val, throw_flag);  /* -> [ ... varname val this ] */
59 	} else {
60 		/* Outside any activation -> put to global. */
61 		DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);
62 		duk_js_putvar_envrec(thr, thr->builtins[DUK_BIDX_GLOBAL_ENV], h_varname, tv_val, throw_flag);
63 	}
64 
65 	/* [ ... varname val ] */
66 
67 	duk_pop_2(ctx);
68 
69 	/* [ ... ] */
70 
71 	return;
72 }
73 
duk_del_var(duk_context * ctx)74 DUK_EXTERNAL duk_bool_t duk_del_var(duk_context *ctx) {
75 	DUK_ASSERT_CTX_VALID(ctx);
76 
77 	DUK_ERROR_UNIMPLEMENTED_DEFMSG((duk_hthread *) ctx);
78 	return 0;
79 }
80 
duk_has_var(duk_context * ctx)81 DUK_EXTERNAL duk_bool_t duk_has_var(duk_context *ctx) {
82 	DUK_ASSERT_CTX_VALID(ctx);
83 
84 	DUK_ERROR_UNIMPLEMENTED_DEFMSG((duk_hthread *) ctx);
85 	return 0;
86 }
87