MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add with() and "use strict"

+113 -13
+1 -1
meson.build
··· 41 41 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 42 42 43 43 version_conf = configuration_data() 44 - version_conf.set('ANT_VERSION', '0.0.5.45') 44 + version_conf.set('ANT_VERSION', '0.0.5.47') 45 45 version_conf.set('ANT_GIT_HASH', git_hash) 46 46 version_conf.set('ANT_BUILD_DATE', build_date) 47 47
+98 -12
src/ant.c
··· 86 86 #define F_RETURN 16U // return has been executed 87 87 #define F_THROW 32U // throw has been executed 88 88 #define F_SWITCH 64U // we are inside a switch statement 89 + #define F_STRICT 128U // strict mode is enabled 89 90 jsoff_t clen; // code snippet length 90 91 jsoff_t pos; // current parsing position 91 92 jsoff_t toff; // offset of the last parsed token ··· 3982 3983 return res; 3983 3984 } 3984 3985 3986 + static jsval_t js_with(struct js *js) { 3987 + uint8_t flags = js->flags, exe = !(flags & F_NOEXEC); 3988 + jsval_t res = js_mkundef(); 3989 + 3990 + if (flags & F_STRICT) { 3991 + return js_mkerr(js, "with statement not allowed in strict mode"); 3992 + } 3993 + 3994 + js->consumed = 1; 3995 + if (!expect(js, TOK_LPAREN, &res)) return res; 3996 + 3997 + jsval_t obj_expr = js_expr(js); 3998 + if (is_err(obj_expr)) return obj_expr; 3999 + 4000 + if (!expect(js, TOK_RPAREN, &res)) return res; 4001 + 4002 + if (exe) { 4003 + jsval_t obj = resolveprop(js, obj_expr); 4004 + if (vtype(obj) != T_OBJ && vtype(obj) != T_ARR && vtype(obj) != T_FUNC) { 4005 + return js_mkerr(js, "with requires object"); 4006 + } 4007 + 4008 + jsval_t with_obj = obj; 4009 + if (vtype(obj) == T_FUNC) { 4010 + with_obj = mkval(T_OBJ, vdata(obj)); 4011 + } 4012 + 4013 + jsoff_t parent_scope_offset = (jsoff_t) vdata(js->scope); 4014 + jsval_t with_scope = mkentity(js, 0 | T_OBJ, &parent_scope_offset, sizeof(parent_scope_offset)); 4015 + 4016 + jsoff_t prop_off = loadoff(js, (jsoff_t) vdata(with_obj)) & ~(3U | CONSTMASK); 4017 + while (prop_off < js->brk && prop_off != 0) { 4018 + jsoff_t koff = loadoff(js, prop_off + (jsoff_t) sizeof(prop_off)); 4019 + jsval_t val = loadval(js, prop_off + (jsoff_t) (sizeof(prop_off) + sizeof(koff))); 4020 + 4021 + jsval_t new_prop = mkprop(js, with_scope, mkval(T_STR, koff), val, false); 4022 + if (is_err(new_prop)) return new_prop; 4023 + 4024 + prop_off = loadoff(js, prop_off) & ~(3U | CONSTMASK); 4025 + } 4026 + 4027 + jsval_t saved_scope = js->scope; 4028 + js->scope = with_scope; 4029 + 4030 + res = js_block_or_stmt(js); 4031 + 4032 + js->scope = saved_scope; 4033 + } else { 4034 + res = js_block_or_stmt(js); 4035 + } 4036 + 4037 + js->flags = flags; 4038 + return res; 4039 + } 4040 + 3985 4041 static jsval_t js_class_decl(struct js *js) { 3986 4042 uint8_t exe = !(js->flags & F_NOEXEC); 3987 4043 js->consumed = 1; ··· 4179 4235 } 4180 4236 } 4181 4237 4238 + static void js_var(struct js *js, jsval_t *res) { 4239 + if (!js->var_warning_shown) { 4240 + fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n"); 4241 + js->var_warning_shown = true; 4242 + } 4243 + *res = js_let(js); 4244 + } 4245 + 4246 + static void js_async(struct js *js, jsval_t *res) { 4247 + js->consumed = 1; 4248 + if (next(js) == TOK_FUNC) { 4249 + *res = js_func_decl_async(js); 4250 + return; 4251 + } 4252 + *res = js_mkerr(js, "async must be followed by function"); 4253 + } 4254 + 4182 4255 static jsval_t js_stmt(struct js *js) { 4183 4256 jsval_t res; 4184 4257 if (js->brk > js->gct) js_gc(js); ··· 4188 4261 case TOK_DEFAULT: case TOK_FINALLY: 4189 4262 res = js_mkerr(js, "SyntaxError '%.*s'", (int) js->tlen, js->code + js->toff); 4190 4263 break; 4191 - case TOK_WITH: case TOK_YIELD: 4192 - res = js_mkerr(js, "'%.*s' not implemented", (int) js->tlen, js->code + js->toff); 4193 - break; 4194 - case TOK_THROW: js_throw_handle(js, &res); break; 4195 - case TOK_VAR: 4196 - if (!js->var_warning_shown) { 4197 - fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n"); 4198 - js->var_warning_shown = true; 4199 - } 4200 - res = js_let(js); 4264 + case TOK_YIELD: 4265 + res = js_mkerr(js, " '%.*s' not implemented", (int) js->tlen, js->code + js->toff); 4201 4266 break; 4267 + case TOK_THROW: js_throw_handle(js, &res); break; 4268 + case TOK_VAR: js_var(js, &res); break; 4269 + case TOK_ASYNC: js_async(js, &res); break; 4270 + case TOK_WITH: res = js_with(js); break; 4202 4271 case TOK_SWITCH: res = js_switch(js); break; 4203 4272 case TOK_WHILE: res = js_while(js); break; 4204 4273 case TOK_DO: res = js_do_while(js); break; ··· 4207 4276 case TOK_LET: res = js_let(js); break; 4208 4277 case TOK_CONST: res = js_const(js); break; 4209 4278 case TOK_FUNC: res = js_func_decl(js); break; 4210 - case TOK_ASYNC: js->consumed = 1; if (next(js) == TOK_FUNC) res = js_func_decl_async(js); else return js_mkerr(js, "async must be followed by function"); break; 4211 4279 case TOK_CLASS: res = js_class_decl(js); break; 4212 4280 case TOK_IF: res = js_if(js); break; 4213 4281 case TOK_LBRACE: res = js_block(js, !(js->flags & F_NOEXEC)); break; 4214 4282 case TOK_FOR: res = js_for(js); break; 4215 4283 case TOK_RETURN: res = js_return(js); break; 4216 - case TOK_TRY: res = js_try(js); break; 4284 + case TOK_TRY: res = js_try(js); break; 4217 4285 default: res = resolveprop(js, js_expr(js)); break; 4218 4286 } 4219 4287 ··· 5815 5883 js->clen = (jsoff_t) len; 5816 5884 js->pos = 0; 5817 5885 js->cstk = &res; 5886 + 5887 + uint8_t saved_tok = js->tok; 5888 + jsoff_t saved_pos = js->pos; 5889 + uint8_t saved_consumed = js->consumed; 5890 + js->consumed = 1; 5891 + 5892 + if (next(js) == TOK_STRING) { 5893 + const char *str = &js->code[js->toff + 1]; 5894 + size_t str_len = js->tlen - 2; 5895 + if (str_len == 10 && memcmp(str, "use strict", 10) == 0) { 5896 + js->flags |= F_STRICT; 5897 + } 5898 + } 5899 + 5900 + js->tok = saved_tok; 5901 + js->pos = saved_pos; 5902 + js->consumed = saved_consumed; 5903 + 5818 5904 while (next(js) != TOK_EOF && !is_err(res)) { 5819 5905 res = js_stmt(js); 5820 5906 if (js->flags & F_RETURN) break;
+7
tests/test_with_strict.cjs
··· 1 + "use strict"; 2 + 3 + // Test 2: with statement should fail with 'use strict' 4 + let obj = { x: 10, y: 20 }; 5 + with (obj) { 6 + console.log("This should not run"); 7 + }
+7
tests/test_without_strict.cjs
··· 1 + // Test 1: with statement should work without 'use strict' 2 + let obj = { x: 10, y: 20 }; 3 + with (obj) { 4 + console.log("Test 1 - x:", x); // should print 10 5 + console.log("Test 1 - y:", y); // should print 20 6 + } 7 + console.log("Test 1 passed");