1 /* 2 * Copyright 2011 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #include <math.h> 20 #include <assert.h> 21 22 #include "jscript.h" 23 #include "engine.h" 24 #include "parser.h" 25 26 #include "wine/rbtree.h" 27 #include "wine/debug.h" 28 29 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 30 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas); 31 32 typedef struct _statement_ctx_t { 33 unsigned stack_use; 34 BOOL using_scope; 35 BOOL using_except; 36 37 unsigned break_label; 38 unsigned continue_label; 39 40 const labelled_statement_t *labelled_stat; 41 42 struct _statement_ctx_t *next; 43 } statement_ctx_t; 44 45 typedef struct { 46 struct wine_rb_entry entry; 47 BSTR name; 48 int ref; 49 } function_local_t; 50 51 typedef struct _compiler_ctx_t { 52 parser_ctx_t *parser; 53 bytecode_t *code; 54 55 BOOL from_eval; 56 57 unsigned code_off; 58 unsigned code_size; 59 60 unsigned *labels; 61 unsigned labels_size; 62 unsigned labels_cnt; 63 64 struct wine_rb_tree locals; 65 unsigned locals_cnt; 66 67 statement_ctx_t *stat_ctx; 68 function_code_t *func; 69 70 function_expression_t *func_head; 71 function_expression_t *func_tail; 72 73 heap_pool_t heap; 74 } compiler_ctx_t; 75 76 static const struct { 77 const char *op_str; 78 instr_arg_type_t arg1_type; 79 instr_arg_type_t arg2_type; 80 } instr_info[] = { 81 #define X(n,a,b,c) {#n,b,c}, 82 OP_LIST 83 #undef X 84 }; 85 86 static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg) 87 { 88 switch(type) { 89 case ARG_STR: 90 TRACE_(jscript_disas)("\t%s", debugstr_jsstr(arg->str)); 91 break; 92 case ARG_BSTR: 93 TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr))); 94 break; 95 case ARG_INT: 96 TRACE_(jscript_disas)("\t%d", arg->uint); 97 break; 98 case ARG_UINT: 99 case ARG_ADDR: 100 TRACE_(jscript_disas)("\t%u", arg->uint); 101 break; 102 case ARG_FUNC: 103 case ARG_NONE: 104 break; 105 DEFAULT_UNREACHABLE; 106 } 107 } 108 109 static void dump_code(compiler_ctx_t *ctx, unsigned off) 110 { 111 instr_t *instr; 112 113 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) { 114 TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str); 115 if(instr_info[instr->op].arg1_type == ARG_DBL) { 116 TRACE_(jscript_disas)("\t%lf", instr->u.dbl); 117 }else { 118 dump_instr_arg(instr_info[instr->op].arg1_type, instr->u.arg); 119 dump_instr_arg(instr_info[instr->op].arg2_type, instr->u.arg+1); 120 } 121 TRACE_(jscript_disas)("\n"); 122 } 123 } 124 125 static HRESULT compile_expression(compiler_ctx_t*,expression_t*,BOOL); 126 static HRESULT compile_statement(compiler_ctx_t*,statement_ctx_t*,statement_t*); 127 128 static inline void *compiler_alloc(bytecode_t *code, size_t size) 129 { 130 return heap_pool_alloc(&code->heap, size); 131 } 132 133 jsstr_t *compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len) 134 { 135 jsstr_t *new_str; 136 137 if(!ctx->code->str_pool_size) { 138 ctx->code->str_pool = heap_alloc(8 * sizeof(jsstr_t*)); 139 if(!ctx->code->str_pool) 140 return NULL; 141 ctx->code->str_pool_size = 8; 142 }else if(ctx->code->str_pool_size == ctx->code->str_cnt) { 143 jsstr_t **new_pool; 144 145 new_pool = heap_realloc(ctx->code->str_pool, ctx->code->str_pool_size*2*sizeof(jsstr_t*)); 146 if(!new_pool) 147 return NULL; 148 149 ctx->code->str_pool = new_pool; 150 ctx->code->str_pool_size *= 2; 151 } 152 153 new_str = jsstr_alloc_len(str, len); 154 if(!new_str) 155 return NULL; 156 157 ctx->code->str_pool[ctx->code->str_cnt++] = new_str; 158 return new_str; 159 } 160 161 static jsstr_t *compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str) 162 { 163 return compiler_alloc_string_len(ctx, str, lstrlenW(str)); 164 } 165 166 static BOOL ensure_bstr_slot(compiler_ctx_t *ctx) 167 { 168 if(!ctx->code->bstr_pool_size) { 169 ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR)); 170 if(!ctx->code->bstr_pool) 171 return FALSE; 172 ctx->code->bstr_pool_size = 8; 173 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) { 174 BSTR *new_pool; 175 176 new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR)); 177 if(!new_pool) 178 return FALSE; 179 180 ctx->code->bstr_pool = new_pool; 181 ctx->code->bstr_pool_size *= 2; 182 } 183 184 return TRUE; 185 } 186 187 static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str) 188 { 189 if(!ensure_bstr_slot(ctx)) 190 return NULL; 191 192 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str); 193 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt]) 194 return NULL; 195 196 return ctx->code->bstr_pool[ctx->code->bstr_cnt++]; 197 } 198 199 static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len) 200 { 201 if(!ensure_bstr_slot(ctx)) 202 return NULL; 203 204 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocStringLen(str, len); 205 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt]) 206 return NULL; 207 208 return ctx->code->bstr_pool[ctx->code->bstr_cnt++]; 209 } 210 211 static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op) 212 { 213 assert(ctx->code_size >= ctx->code_off); 214 215 if(ctx->code_size == ctx->code_off) { 216 instr_t *new_instrs; 217 218 new_instrs = heap_realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t)); 219 if(!new_instrs) 220 return 0; 221 222 ctx->code->instrs = new_instrs; 223 ctx->code_size *= 2; 224 } 225 226 ctx->code->instrs[ctx->code_off].op = op; 227 return ctx->code_off++; 228 } 229 230 static inline instr_t *instr_ptr(compiler_ctx_t *ctx, unsigned off) 231 { 232 assert(off < ctx->code_off); 233 return ctx->code->instrs + off; 234 } 235 236 static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg) 237 { 238 unsigned instr; 239 240 instr = push_instr(ctx, op); 241 if(!instr) 242 return E_OUTOFMEMORY; 243 244 instr_ptr(ctx, instr)->u.arg->lng = arg; 245 return S_OK; 246 } 247 248 static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str) 249 { 250 unsigned instr; 251 252 instr = push_instr(ctx, op); 253 if(!instr) 254 return E_OUTOFMEMORY; 255 256 instr_ptr(ctx, instr)->u.arg->str = str; 257 return S_OK; 258 } 259 260 static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2) 261 { 262 unsigned instr; 263 264 instr = push_instr(ctx, op); 265 if(!instr) 266 return E_OUTOFMEMORY; 267 268 instr_ptr(ctx, instr)->u.arg[0].str = str; 269 instr_ptr(ctx, instr)->u.arg[1].uint = arg2; 270 return S_OK; 271 } 272 273 static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg) 274 { 275 unsigned instr; 276 WCHAR *str; 277 278 str = compiler_alloc_bstr(ctx, arg); 279 if(!str) 280 return E_OUTOFMEMORY; 281 282 instr = push_instr(ctx, op); 283 if(!instr) 284 return E_OUTOFMEMORY; 285 286 instr_ptr(ctx, instr)->u.arg->bstr = str; 287 return S_OK; 288 } 289 290 static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2) 291 { 292 unsigned instr; 293 WCHAR *str; 294 295 str = compiler_alloc_bstr(ctx, arg1); 296 if(!str) 297 return E_OUTOFMEMORY; 298 299 instr = push_instr(ctx, op); 300 if(!instr) 301 return E_OUTOFMEMORY; 302 303 instr_ptr(ctx, instr)->u.arg[0].bstr = str; 304 instr_ptr(ctx, instr)->u.arg[1].uint = arg2; 305 return S_OK; 306 } 307 308 static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2) 309 { 310 unsigned instr; 311 jsstr_t *str; 312 313 str = compiler_alloc_string(ctx, arg2); 314 if(!str) 315 return E_OUTOFMEMORY; 316 317 instr = push_instr(ctx, op); 318 if(!instr) 319 return E_OUTOFMEMORY; 320 321 instr_ptr(ctx, instr)->u.arg[0].uint = arg1; 322 instr_ptr(ctx, instr)->u.arg[1].str = str; 323 return S_OK; 324 } 325 326 static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg) 327 { 328 unsigned instr; 329 330 instr = push_instr(ctx, op); 331 if(!instr) 332 return E_OUTOFMEMORY; 333 334 instr_ptr(ctx, instr)->u.dbl = arg; 335 return S_OK; 336 } 337 338 static inline void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg) 339 { 340 instr_ptr(ctx, instr)->u.arg->uint = arg; 341 } 342 343 static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg) 344 { 345 unsigned instr; 346 347 instr = push_instr(ctx, op); 348 if(!instr) 349 return E_OUTOFMEMORY; 350 351 set_arg_uint(ctx, instr, arg); 352 return S_OK; 353 } 354 355 static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op) 356 { 357 HRESULT hres; 358 359 hres = compile_expression(ctx, expr->expression1, TRUE); 360 if(FAILED(hres)) 361 return hres; 362 363 hres = compile_expression(ctx, expr->expression2, TRUE); 364 if(FAILED(hres)) 365 return hres; 366 367 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY; 368 } 369 370 static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op) 371 { 372 HRESULT hres; 373 374 hres = compile_expression(ctx, expr->expression, TRUE); 375 if(FAILED(hres)) 376 return hres; 377 378 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY; 379 } 380 381 /* ECMA-262 3rd Edition 11.2.1 */ 382 static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr) 383 { 384 HRESULT hres; 385 386 hres = compile_expression(ctx, expr->expression, TRUE); 387 if(FAILED(hres)) 388 return hres; 389 390 return push_instr_bstr(ctx, OP_member, expr->identifier); 391 } 392 393 #define LABEL_FLAG 0x80000000 394 395 static unsigned alloc_label(compiler_ctx_t *ctx) 396 { 397 if(!ctx->labels_size) { 398 ctx->labels = heap_alloc(8 * sizeof(*ctx->labels)); 399 if(!ctx->labels) 400 return 0; 401 ctx->labels_size = 8; 402 }else if(ctx->labels_size == ctx->labels_cnt) { 403 unsigned *new_labels; 404 405 new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels)); 406 if(!new_labels) 407 return 0; 408 409 ctx->labels = new_labels; 410 ctx->labels_size *= 2; 411 } 412 413 return ctx->labels_cnt++ | LABEL_FLAG; 414 } 415 416 static void label_set_addr(compiler_ctx_t *ctx, unsigned label) 417 { 418 assert(label & LABEL_FLAG); 419 ctx->labels[label & ~LABEL_FLAG] = ctx->code_off; 420 } 421 422 static inline BOOL is_memberid_expr(expression_type_t type) 423 { 424 return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY; 425 } 426 427 static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref) 428 { 429 statement_ctx_t *iter; 430 local_ref_t *ref; 431 432 for(iter = ctx->stat_ctx; iter; iter = iter->next) { 433 if(iter->using_scope) 434 return FALSE; 435 } 436 437 ref = lookup_local(ctx->func, identifier); 438 if(!ref) 439 return FALSE; 440 441 *ret_ref = ref->ref; 442 return TRUE; 443 } 444 445 static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags) 446 { 447 int local_ref; 448 if(bind_local(ctx, identifier, &local_ref)) 449 return push_instr_int(ctx, OP_local_ref, local_ref); 450 return push_instr_bstr_uint(ctx, OP_identid, identifier, flags); 451 } 452 453 static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier) 454 { 455 int local_ref; 456 if(bind_local(ctx, identifier, &local_ref)) 457 return push_instr_int(ctx, OP_local, local_ref); 458 return push_instr_bstr(ctx, OP_ident, identifier); 459 } 460 461 static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags) 462 { 463 HRESULT hres = S_OK; 464 465 switch(expr->type) { 466 case EXPR_IDENT: { 467 identifier_expression_t *ident_expr = (identifier_expression_t*)expr; 468 469 hres = emit_identifier_ref(ctx, ident_expr->identifier, flags); 470 break; 471 } 472 case EXPR_ARRAY: { 473 binary_expression_t *array_expr = (binary_expression_t*)expr; 474 475 hres = compile_expression(ctx, array_expr->expression1, TRUE); 476 if(FAILED(hres)) 477 return hres; 478 479 hres = compile_expression(ctx, array_expr->expression2, TRUE); 480 if(FAILED(hres)) 481 return hres; 482 483 hres = push_instr_uint(ctx, OP_memberid, flags); 484 break; 485 } 486 case EXPR_MEMBER: { 487 member_expression_t *member_expr = (member_expression_t*)expr; 488 jsstr_t *jsstr; 489 490 hres = compile_expression(ctx, member_expr->expression, TRUE); 491 if(FAILED(hres)) 492 return hres; 493 494 /* FIXME: Potential optimization */ 495 jsstr = compiler_alloc_string(ctx, member_expr->identifier); 496 if(!jsstr) 497 return E_OUTOFMEMORY; 498 499 hres = push_instr_str(ctx, OP_str, jsstr); 500 if(FAILED(hres)) 501 return hres; 502 503 hres = push_instr_uint(ctx, OP_memberid, flags); 504 break; 505 } 506 DEFAULT_UNREACHABLE; 507 } 508 509 return hres; 510 } 511 512 static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n) 513 { 514 HRESULT hres; 515 516 if(!is_memberid_expr(expr->expression->type)) { 517 hres = compile_expression(ctx, expr->expression, TRUE); 518 if(FAILED(hres)) 519 return hres; 520 521 return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN); 522 } 523 524 hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure); 525 if(FAILED(hres)) 526 return hres; 527 528 return push_instr_int(ctx, op, n); 529 } 530 531 /* ECMA-262 3rd Edition 11.14 */ 532 static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret) 533 { 534 HRESULT hres; 535 536 hres = compile_expression(ctx, expr->expression1, FALSE); 537 if(FAILED(hres)) 538 return hres; 539 540 return compile_expression(ctx, expr->expression2, emit_ret); 541 } 542 543 /* ECMA-262 3rd Edition 11.11 */ 544 static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op) 545 { 546 unsigned instr; 547 HRESULT hres; 548 549 hres = compile_expression(ctx, expr->expression1, TRUE); 550 if(FAILED(hres)) 551 return hres; 552 553 instr = push_instr(ctx, op); 554 if(!instr) 555 return E_OUTOFMEMORY; 556 557 hres = compile_expression(ctx, expr->expression2, TRUE); 558 if(FAILED(hres)) 559 return hres; 560 561 set_arg_uint(ctx, instr, ctx->code_off); 562 return S_OK; 563 } 564 565 /* ECMA-262 3rd Edition 11.12 */ 566 static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr) 567 { 568 unsigned jmp_false, jmp_end; 569 HRESULT hres; 570 571 hres = compile_expression(ctx, expr->expression, TRUE); 572 if(FAILED(hres)) 573 return hres; 574 575 jmp_false = push_instr(ctx, OP_cnd_z); 576 if(!jmp_false) 577 return E_OUTOFMEMORY; 578 579 hres = compile_expression(ctx, expr->true_expression, TRUE); 580 if(FAILED(hres)) 581 return hres; 582 583 jmp_end = push_instr(ctx, OP_jmp); 584 if(!jmp_end) 585 return E_OUTOFMEMORY; 586 587 set_arg_uint(ctx, jmp_false, ctx->code_off); 588 hres = push_instr_uint(ctx, OP_pop, 1); 589 if(FAILED(hres)) 590 return hres; 591 592 hres = compile_expression(ctx, expr->false_expression, TRUE); 593 if(FAILED(hres)) 594 return hres; 595 596 set_arg_uint(ctx, jmp_end, ctx->code_off); 597 return S_OK; 598 } 599 600 static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr) 601 { 602 unsigned arg_cnt = 0; 603 argument_t *arg; 604 HRESULT hres; 605 606 hres = compile_expression(ctx, expr->expression, TRUE); 607 if(FAILED(hres)) 608 return hres; 609 610 for(arg = expr->argument_list; arg; arg = arg->next) { 611 hres = compile_expression(ctx, arg->expr, TRUE); 612 if(FAILED(hres)) 613 return hres; 614 arg_cnt++; 615 } 616 617 hres = push_instr_uint(ctx, OP_new, arg_cnt); 618 if(FAILED(hres)) 619 return hres; 620 621 hres = push_instr_uint(ctx, OP_pop, arg_cnt+1); 622 if(FAILED(hres)) 623 return hres; 624 625 return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY; 626 } 627 628 static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret) 629 { 630 unsigned arg_cnt = 0, extra_args; 631 argument_t *arg; 632 unsigned instr; 633 jsop_t op; 634 HRESULT hres; 635 636 if(is_memberid_expr(expr->expression->type)) { 637 op = OP_call_member; 638 extra_args = 2; 639 hres = compile_memberid_expression(ctx, expr->expression, 0); 640 }else { 641 op = OP_call; 642 extra_args = 1; 643 hres = compile_expression(ctx, expr->expression, TRUE); 644 } 645 646 if(FAILED(hres)) 647 return hres; 648 649 for(arg = expr->argument_list; arg; arg = arg->next) { 650 hres = compile_expression(ctx, arg->expr, TRUE); 651 if(FAILED(hres)) 652 return hres; 653 arg_cnt++; 654 } 655 656 instr = push_instr(ctx, op); 657 if(!instr) 658 return E_OUTOFMEMORY; 659 660 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt; 661 instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret; 662 663 hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args); 664 if(FAILED(hres)) 665 return hres; 666 667 return !emit_ret || push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY; 668 } 669 670 static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr) 671 { 672 HRESULT hres; 673 674 switch(expr->expression->type) { 675 case EXPR_ARRAY: { 676 binary_expression_t *array_expr = (binary_expression_t*)expr->expression; 677 678 hres = compile_expression(ctx, array_expr->expression1, TRUE); 679 if(FAILED(hres)) 680 return hres; 681 682 hres = compile_expression(ctx, array_expr->expression2, TRUE); 683 if(FAILED(hres)) 684 return hres; 685 686 if(!push_instr(ctx, OP_delete)) 687 return E_OUTOFMEMORY; 688 break; 689 } 690 case EXPR_MEMBER: { 691 member_expression_t *member_expr = (member_expression_t*)expr->expression; 692 jsstr_t *jsstr; 693 694 hres = compile_expression(ctx, member_expr->expression, TRUE); 695 if(FAILED(hres)) 696 return hres; 697 698 /* FIXME: Potential optimization */ 699 jsstr = compiler_alloc_string(ctx, member_expr->identifier); 700 if(!jsstr) 701 return E_OUTOFMEMORY; 702 703 hres = push_instr_str(ctx, OP_str, jsstr); 704 if(FAILED(hres)) 705 return hres; 706 707 if(!push_instr(ctx, OP_delete)) 708 return E_OUTOFMEMORY; 709 break; 710 } 711 case EXPR_IDENT: 712 return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier); 713 default: { 714 static const WCHAR fixmeW[] = {'F','I','X','M','E',0}; 715 716 WARN("invalid delete, unimplemented exception message\n"); 717 718 hres = compile_expression(ctx, expr->expression, TRUE); 719 if(FAILED(hres)) 720 return hres; 721 722 return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, fixmeW); 723 } 724 } 725 726 return S_OK; 727 } 728 729 static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op) 730 { 731 BOOL use_throw_path = FALSE; 732 unsigned arg_cnt = 0; 733 HRESULT hres; 734 735 if(expr->expression1->type == EXPR_CALL) { 736 call_expression_t *call_expr = (call_expression_t*)expr->expression1; 737 argument_t *arg; 738 739 if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) { 740 hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure); 741 if(FAILED(hres)) 742 return hres; 743 744 for(arg = call_expr->argument_list; arg; arg = arg->next) { 745 hres = compile_expression(ctx, arg->expr, TRUE); 746 if(FAILED(hres)) 747 return hres; 748 arg_cnt++; 749 } 750 751 if(op != OP_LAST) { 752 unsigned instr; 753 754 /* We need to call the functions twice: to get the value and to set it. 755 * JavaScript interpreted functions may to modify value on the stack, 756 * but assignment calls are allowed only on external functions, so we 757 * may reuse the stack here. */ 758 instr = push_instr(ctx, OP_call_member); 759 if(!instr) 760 return E_OUTOFMEMORY; 761 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt; 762 instr_ptr(ctx, instr)->u.arg[1].lng = 1; 763 764 if(!push_instr(ctx, OP_push_acc)) 765 return E_OUTOFMEMORY; 766 } 767 }else { 768 use_throw_path = TRUE; 769 } 770 }else if(is_memberid_expr(expr->expression1->type)) { 771 hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure); 772 if(FAILED(hres)) 773 return hres; 774 if(op != OP_LAST && !push_instr(ctx, OP_refval)) 775 return E_OUTOFMEMORY; 776 }else { 777 use_throw_path = TRUE; 778 } 779 780 if(use_throw_path) { 781 /* Illegal assignment: evaluate and throw */ 782 hres = compile_expression(ctx, expr->expression1, TRUE); 783 if(FAILED(hres)) 784 return hres; 785 786 hres = compile_expression(ctx, expr->expression2, TRUE); 787 if(FAILED(hres)) 788 return hres; 789 790 if(op != OP_LAST && !push_instr(ctx, op)) 791 return E_OUTOFMEMORY; 792 793 return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN); 794 } 795 796 hres = compile_expression(ctx, expr->expression2, TRUE); 797 if(FAILED(hres)) 798 return hres; 799 800 if(op != OP_LAST && !push_instr(ctx, op)) 801 return E_OUTOFMEMORY; 802 803 if(arg_cnt) 804 return push_instr_uint(ctx, OP_assign_call, arg_cnt); 805 806 if(!push_instr(ctx, OP_assign)) 807 return E_OUTOFMEMORY; 808 809 return S_OK; 810 } 811 812 static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr) 813 { 814 jsop_t op; 815 HRESULT hres; 816 817 if(is_memberid_expr(expr->expression->type)) { 818 if(expr->expression->type == EXPR_IDENT) 819 return push_instr_bstr(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier); 820 821 op = OP_typeofid; 822 hres = compile_memberid_expression(ctx, expr->expression, 0); 823 }else { 824 op = OP_typeof; 825 hres = compile_expression(ctx, expr->expression, TRUE); 826 } 827 if(FAILED(hres)) 828 return hres; 829 830 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY; 831 } 832 833 static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal) 834 { 835 switch(literal->type) { 836 case LT_BOOL: 837 return push_instr_int(ctx, OP_bool, literal->u.bval); 838 case LT_DOUBLE: 839 return push_instr_double(ctx, OP_double, literal->u.dval); 840 case LT_NULL: 841 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY; 842 case LT_STRING: 843 return push_instr_str(ctx, OP_str, literal->u.str); 844 case LT_REGEXP: 845 return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags); 846 DEFAULT_UNREACHABLE; 847 } 848 return E_FAIL; 849 } 850 851 static HRESULT literal_as_string(compiler_ctx_t *ctx, literal_t *literal, jsstr_t **str) 852 { 853 switch(literal->type) { 854 case LT_STRING: 855 *str = literal->u.str; 856 break; 857 case LT_DOUBLE: 858 return double_to_string(literal->u.dval, str); 859 DEFAULT_UNREACHABLE; 860 } 861 862 return *str ? S_OK : E_OUTOFMEMORY; 863 } 864 865 static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr) 866 { 867 unsigned length = 0; 868 array_element_t *iter; 869 unsigned array_instr; 870 HRESULT hres; 871 872 array_instr = push_instr(ctx, OP_carray); 873 874 for(iter = expr->element_list; iter; iter = iter->next) { 875 length += iter->elision; 876 877 hres = compile_expression(ctx, iter->expr, TRUE); 878 if(FAILED(hres)) 879 return hres; 880 881 hres = push_instr_uint(ctx, OP_carray_set, length); 882 if(FAILED(hres)) 883 return hres; 884 885 length++; 886 } 887 888 instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length; 889 return S_OK; 890 } 891 892 static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr) 893 { 894 property_definition_t *iter; 895 jsstr_t *name; 896 HRESULT hres; 897 898 if(!push_instr(ctx, OP_new_obj)) 899 return E_OUTOFMEMORY; 900 901 for(iter = expr->property_list; iter; iter = iter->next) { 902 hres = literal_as_string(ctx, iter->name, &name); 903 if(FAILED(hres)) 904 return hres; 905 906 hres = compile_expression(ctx, iter->value, TRUE); 907 if(FAILED(hres)) 908 return hres; 909 910 hres = push_instr_str_uint(ctx, OP_obj_prop, name, iter->type); 911 if(FAILED(hres)) 912 return hres; 913 } 914 915 return S_OK; 916 } 917 918 static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret) 919 { 920 return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK; 921 } 922 923 static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr, BOOL emit_ret) 924 { 925 HRESULT hres; 926 927 switch(expr->type) { 928 case EXPR_ADD: 929 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add); 930 break; 931 case EXPR_AND: 932 hres = compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_z); 933 break; 934 case EXPR_ARRAY: 935 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_array); 936 break; 937 case EXPR_ARRAYLIT: 938 hres = compile_array_literal(ctx, (array_literal_expression_t*)expr); 939 break; 940 case EXPR_ASSIGN: 941 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST); 942 break; 943 case EXPR_ASSIGNADD: 944 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_add); 945 break; 946 case EXPR_ASSIGNAND: 947 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_and); 948 break; 949 case EXPR_ASSIGNSUB: 950 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_sub); 951 break; 952 case EXPR_ASSIGNMUL: 953 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mul); 954 break; 955 case EXPR_ASSIGNDIV: 956 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_div); 957 break; 958 case EXPR_ASSIGNMOD: 959 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mod); 960 break; 961 case EXPR_ASSIGNOR: 962 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_or); 963 break; 964 case EXPR_ASSIGNLSHIFT: 965 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_lshift); 966 break; 967 case EXPR_ASSIGNRSHIFT: 968 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift); 969 break; 970 case EXPR_ASSIGNRRSHIFT: 971 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift2); 972 break; 973 case EXPR_ASSIGNXOR: 974 hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_xor); 975 break; 976 case EXPR_BAND: 977 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and); 978 break; 979 case EXPR_BITNEG: 980 hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg); 981 break; 982 case EXPR_BOR: 983 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or); 984 break; 985 case EXPR_CALL: 986 return compile_call_expression(ctx, (call_expression_t*)expr, emit_ret); 987 case EXPR_COMMA: 988 return compile_comma_expression(ctx, (binary_expression_t*)expr, emit_ret); 989 case EXPR_COND: 990 hres = compile_conditional_expression(ctx, (conditional_expression_t*)expr); 991 break; 992 case EXPR_DELETE: 993 hres = compile_delete_expression(ctx, (unary_expression_t*)expr); 994 break; 995 case EXPR_DIV: 996 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div); 997 break; 998 case EXPR_EQ: 999 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq); 1000 break; 1001 case EXPR_EQEQ: 1002 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2); 1003 break; 1004 case EXPR_FUNC: 1005 return compile_function_expression(ctx, (function_expression_t*)expr, emit_ret); 1006 case EXPR_GREATER: 1007 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt); 1008 break; 1009 case EXPR_GREATEREQ: 1010 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq); 1011 break; 1012 case EXPR_IDENT: 1013 hres = emit_identifier(ctx, ((identifier_expression_t*)expr)->identifier); 1014 break; 1015 case EXPR_IN: 1016 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in); 1017 break; 1018 case EXPR_INSTANCEOF: 1019 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof); 1020 break; 1021 case EXPR_LESS: 1022 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt); 1023 break; 1024 case EXPR_LESSEQ: 1025 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq); 1026 break; 1027 case EXPR_LITERAL: 1028 hres = compile_literal(ctx, ((literal_expression_t*)expr)->literal); 1029 break; 1030 case EXPR_LOGNEG: 1031 hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg); 1032 break; 1033 case EXPR_LSHIFT: 1034 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lshift); 1035 break; 1036 case EXPR_MEMBER: 1037 hres = compile_member_expression(ctx, (member_expression_t*)expr); 1038 break; 1039 case EXPR_MINUS: 1040 hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus); 1041 break; 1042 case EXPR_MOD: 1043 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod); 1044 break; 1045 case EXPR_MUL: 1046 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul); 1047 break; 1048 case EXPR_NEW: 1049 hres = compile_new_expression(ctx, (call_expression_t*)expr); 1050 break; 1051 case EXPR_NOTEQ: 1052 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq); 1053 break; 1054 case EXPR_NOTEQEQ: 1055 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq2); 1056 break; 1057 case EXPR_OR: 1058 hres = compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_nz); 1059 break; 1060 case EXPR_PLUS: 1061 hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_tonum); 1062 break; 1063 case EXPR_POSTDEC: 1064 hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, -1); 1065 break; 1066 case EXPR_POSTINC: 1067 hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, 1); 1068 break; 1069 case EXPR_PREDEC: 1070 hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, -1); 1071 break; 1072 case EXPR_PREINC: 1073 hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, 1); 1074 break; 1075 case EXPR_PROPVAL: 1076 hres = compile_object_literal(ctx, (property_value_expression_t*)expr); 1077 break; 1078 case EXPR_RSHIFT: 1079 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift); 1080 break; 1081 case EXPR_RRSHIFT: 1082 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift2); 1083 break; 1084 case EXPR_SUB: 1085 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub); 1086 break; 1087 case EXPR_THIS: 1088 return !emit_ret || push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY; 1089 case EXPR_TYPEOF: 1090 hres = compile_typeof_expression(ctx, (unary_expression_t*)expr); 1091 break; 1092 case EXPR_VOID: 1093 hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_void); 1094 break; 1095 case EXPR_BXOR: 1096 hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor); 1097 break; 1098 DEFAULT_UNREACHABLE; 1099 } 1100 1101 if(FAILED(hres)) 1102 return hres; 1103 1104 return emit_ret ? S_OK : push_instr_uint(ctx, OP_pop, 1); 1105 } 1106 1107 static inline BOOL is_loop_statement(statement_type_t type) 1108 { 1109 return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE; 1110 } 1111 1112 /* ECMA-262 3rd Edition 12.1 */ 1113 static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter) 1114 { 1115 HRESULT hres; 1116 1117 while(iter) { 1118 hres = compile_statement(ctx, NULL, iter); 1119 if(FAILED(hres)) 1120 return hres; 1121 1122 iter = iter->next; 1123 } 1124 1125 return S_OK; 1126 } 1127 1128 /* ECMA-262 3rd Edition 12.2 */ 1129 static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list) 1130 { 1131 variable_declaration_t *iter; 1132 HRESULT hres; 1133 1134 assert(list != NULL); 1135 1136 for(iter = list; iter; iter = iter->next) { 1137 if(!iter->expr) 1138 continue; 1139 1140 hres = emit_identifier_ref(ctx, iter->identifier, 0); 1141 if(FAILED(hres)) 1142 return hres; 1143 1144 hres = compile_expression(ctx, iter->expr, TRUE); 1145 if(FAILED(hres)) 1146 return hres; 1147 1148 if(!push_instr(ctx, OP_assign)) 1149 return E_OUTOFMEMORY; 1150 1151 hres = push_instr_uint(ctx, OP_pop, 1); 1152 if(FAILED(hres)) 1153 return hres; 1154 } 1155 1156 return S_OK; 1157 } 1158 1159 /* ECMA-262 3rd Edition 12.2 */ 1160 static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat) 1161 { 1162 return compile_variable_list(ctx, stat->variable_list); 1163 } 1164 1165 /* ECMA-262 3rd Edition 12.4 */ 1166 static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat) 1167 { 1168 HRESULT hres; 1169 1170 hres = compile_expression(ctx, stat->expr, ctx->from_eval); 1171 if(FAILED(hres)) 1172 return hres; 1173 1174 return !ctx->from_eval || push_instr(ctx, OP_setret) ? S_OK : E_OUTOFMEMORY; 1175 } 1176 1177 /* ECMA-262 3rd Edition 12.5 */ 1178 static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat) 1179 { 1180 unsigned jmp_else; 1181 HRESULT hres; 1182 1183 hres = compile_expression(ctx, stat->expr, TRUE); 1184 if(FAILED(hres)) 1185 return hres; 1186 1187 jmp_else = push_instr(ctx, OP_jmp_z); 1188 if(!jmp_else) 1189 return E_OUTOFMEMORY; 1190 1191 hres = compile_statement(ctx, NULL, stat->if_stat); 1192 if(FAILED(hres)) 1193 return hres; 1194 1195 if(stat->else_stat) { 1196 unsigned jmp_end; 1197 1198 jmp_end = push_instr(ctx, OP_jmp); 1199 if(!jmp_end) 1200 return E_OUTOFMEMORY; 1201 1202 set_arg_uint(ctx, jmp_else, ctx->code_off); 1203 1204 hres = compile_statement(ctx, NULL, stat->else_stat); 1205 if(FAILED(hres)) 1206 return hres; 1207 1208 set_arg_uint(ctx, jmp_end, ctx->code_off); 1209 }else { 1210 set_arg_uint(ctx, jmp_else, ctx->code_off); 1211 } 1212 1213 return S_OK; 1214 } 1215 1216 /* ECMA-262 3rd Edition 12.6.2 */ 1217 static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat) 1218 { 1219 statement_ctx_t stat_ctx = {0, FALSE, FALSE}; 1220 unsigned jmp_off; 1221 HRESULT hres; 1222 1223 stat_ctx.break_label = alloc_label(ctx); 1224 if(!stat_ctx.break_label) 1225 return E_OUTOFMEMORY; 1226 1227 stat_ctx.continue_label = alloc_label(ctx); 1228 if(!stat_ctx.continue_label) 1229 return E_OUTOFMEMORY; 1230 1231 jmp_off = ctx->code_off; 1232 1233 if(!stat->do_while) { 1234 label_set_addr(ctx, stat_ctx.continue_label); 1235 hres = compile_expression(ctx, stat->expr, TRUE); 1236 if(FAILED(hres)) 1237 return hres; 1238 1239 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label); 1240 if(FAILED(hres)) 1241 return hres; 1242 } 1243 1244 hres = compile_statement(ctx, &stat_ctx, stat->statement); 1245 if(FAILED(hres)) 1246 return hres; 1247 1248 if(stat->do_while) { 1249 label_set_addr(ctx, stat_ctx.continue_label); 1250 hres = compile_expression(ctx, stat->expr, TRUE); 1251 if(FAILED(hres)) 1252 return hres; 1253 1254 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label); 1255 if(FAILED(hres)) 1256 return hres; 1257 } 1258 1259 hres = push_instr_uint(ctx, OP_jmp, jmp_off); 1260 if(FAILED(hres)) 1261 return hres; 1262 1263 label_set_addr(ctx, stat_ctx.break_label); 1264 return S_OK; 1265 } 1266 1267 /* ECMA-262 3rd Edition 12.6.3 */ 1268 static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat) 1269 { 1270 statement_ctx_t stat_ctx = {0, FALSE, FALSE}; 1271 unsigned expr_off; 1272 HRESULT hres; 1273 1274 if(stat->variable_list) { 1275 hres = compile_variable_list(ctx, stat->variable_list); 1276 if(FAILED(hres)) 1277 return hres; 1278 }else if(stat->begin_expr) { 1279 hres = compile_expression(ctx, stat->begin_expr, FALSE); 1280 if(FAILED(hres)) 1281 return hres; 1282 } 1283 1284 stat_ctx.break_label = alloc_label(ctx); 1285 if(!stat_ctx.break_label) 1286 return E_OUTOFMEMORY; 1287 1288 stat_ctx.continue_label = alloc_label(ctx); 1289 if(!stat_ctx.continue_label) 1290 return E_OUTOFMEMORY; 1291 1292 expr_off = ctx->code_off; 1293 1294 if(stat->expr) { 1295 hres = compile_expression(ctx, stat->expr, TRUE); 1296 if(FAILED(hres)) 1297 return hres; 1298 1299 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label); 1300 if(FAILED(hres)) 1301 return hres; 1302 } 1303 1304 hres = compile_statement(ctx, &stat_ctx, stat->statement); 1305 if(FAILED(hres)) 1306 return hres; 1307 1308 label_set_addr(ctx, stat_ctx.continue_label); 1309 1310 if(stat->end_expr) { 1311 hres = compile_expression(ctx, stat->end_expr, FALSE); 1312 if(FAILED(hres)) 1313 return hres; 1314 } 1315 1316 hres = push_instr_uint(ctx, OP_jmp, expr_off); 1317 if(FAILED(hres)) 1318 return hres; 1319 1320 label_set_addr(ctx, stat_ctx.break_label); 1321 return S_OK; 1322 } 1323 1324 /* ECMA-262 3rd Edition 12.6.4 */ 1325 static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat) 1326 { 1327 statement_ctx_t stat_ctx = {4, FALSE, FALSE}; 1328 HRESULT hres; 1329 1330 if(stat->variable) { 1331 hres = compile_variable_list(ctx, stat->variable); 1332 if(FAILED(hres)) 1333 return hres; 1334 } 1335 1336 stat_ctx.break_label = alloc_label(ctx); 1337 if(!stat_ctx.break_label) 1338 return E_OUTOFMEMORY; 1339 1340 stat_ctx.continue_label = alloc_label(ctx); 1341 if(!stat_ctx.continue_label) 1342 return E_OUTOFMEMORY; 1343 1344 hres = compile_expression(ctx, stat->in_expr, TRUE); 1345 if(FAILED(hres)) 1346 return hres; 1347 1348 if(stat->variable) { 1349 hres = emit_identifier_ref(ctx, stat->variable->identifier, fdexNameEnsure); 1350 if(FAILED(hres)) 1351 return hres; 1352 }else if(is_memberid_expr(stat->expr->type)) { 1353 hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure); 1354 if(FAILED(hres)) 1355 return hres; 1356 }else { 1357 hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN); 1358 if(FAILED(hres)) 1359 return hres; 1360 1361 /* FIXME: compile statement anyways when we depend on compiler to check errors */ 1362 return S_OK; 1363 } 1364 1365 hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM); 1366 if(FAILED(hres)) 1367 return hres; 1368 1369 label_set_addr(ctx, stat_ctx.continue_label); 1370 hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label); 1371 if(FAILED(hres)) 1372 return E_OUTOFMEMORY; 1373 1374 hres = compile_statement(ctx, &stat_ctx, stat->statement); 1375 if(FAILED(hres)) 1376 return hres; 1377 1378 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label); 1379 if(FAILED(hres)) 1380 return hres; 1381 1382 label_set_addr(ctx, stat_ctx.break_label); 1383 return S_OK; 1384 } 1385 1386 static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx) 1387 { 1388 unsigned stack_pop = 0; 1389 statement_ctx_t *iter; 1390 HRESULT hres; 1391 1392 for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) { 1393 if(iter->using_scope && !push_instr(ctx, OP_pop_scope)) 1394 return E_OUTOFMEMORY; 1395 if(iter->using_except) { 1396 if(stack_pop) { 1397 hres = push_instr_uint(ctx, OP_pop, stack_pop); 1398 if(FAILED(hres)) 1399 return hres; 1400 stack_pop = 0; 1401 } 1402 hres = push_instr_uint(ctx, OP_pop_except, ctx->code_off+1); 1403 if(FAILED(hres)) 1404 return hres; 1405 } 1406 stack_pop += iter->stack_use; 1407 } 1408 1409 if(stack_pop) { 1410 hres = push_instr_uint(ctx, OP_pop, stack_pop); 1411 if(FAILED(hres)) 1412 return hres; 1413 } 1414 1415 return S_OK; 1416 } 1417 1418 /* ECMA-262 3rd Edition 12.7 */ 1419 static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat) 1420 { 1421 statement_ctx_t *pop_ctx; 1422 HRESULT hres; 1423 1424 if(stat->identifier) { 1425 statement_t *label_stat; 1426 statement_ctx_t *iter; 1427 1428 pop_ctx = NULL; 1429 1430 for(iter = ctx->stat_ctx; iter; iter = iter->next) { 1431 if(iter->continue_label) 1432 pop_ctx = iter; 1433 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) 1434 break; 1435 } 1436 1437 if(!iter) { 1438 WARN("Label not found\n"); 1439 return JS_E_LABEL_NOT_FOUND; 1440 } 1441 1442 /* Labelled continue are allowed only on loops */ 1443 for(label_stat = iter->labelled_stat->statement; 1444 label_stat->type == STAT_LABEL; 1445 label_stat = ((labelled_statement_t*)label_stat)->statement); 1446 if(!is_loop_statement(label_stat->type)) { 1447 WARN("Label is not a loop\n"); 1448 return JS_E_INVALID_CONTINUE; 1449 } 1450 1451 assert(pop_ctx != NULL); 1452 }else { 1453 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) { 1454 if(pop_ctx->continue_label) 1455 break; 1456 } 1457 1458 if(!pop_ctx) { 1459 WARN("continue outside loop\n"); 1460 return JS_E_INVALID_CONTINUE; 1461 } 1462 } 1463 1464 hres = pop_to_stat(ctx, pop_ctx); 1465 if(FAILED(hres)) 1466 return hres; 1467 1468 return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label); 1469 } 1470 1471 /* ECMA-262 3rd Edition 12.8 */ 1472 static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat) 1473 { 1474 statement_ctx_t *pop_ctx; 1475 HRESULT hres; 1476 1477 if(stat->identifier) { 1478 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) { 1479 if(pop_ctx->labelled_stat && !wcscmp(pop_ctx->labelled_stat->identifier, stat->identifier)) { 1480 assert(pop_ctx->break_label); 1481 break; 1482 } 1483 } 1484 1485 if(!pop_ctx) { 1486 WARN("Label not found\n"); 1487 return JS_E_LABEL_NOT_FOUND; 1488 } 1489 }else { 1490 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) { 1491 if(pop_ctx->break_label && !pop_ctx->labelled_stat) 1492 break; 1493 } 1494 1495 if(!pop_ctx) { 1496 WARN("Break outside loop\n"); 1497 return JS_E_INVALID_BREAK; 1498 } 1499 } 1500 1501 hres = pop_to_stat(ctx, pop_ctx->next); 1502 if(FAILED(hres)) 1503 return hres; 1504 1505 return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label); 1506 } 1507 1508 /* ECMA-262 3rd Edition 12.9 */ 1509 static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat) 1510 { 1511 HRESULT hres; 1512 1513 if(ctx->from_eval) { 1514 WARN("misplaced return statement\n"); 1515 return JS_E_MISPLACED_RETURN; 1516 } 1517 1518 if(stat->expr) { 1519 hres = compile_expression(ctx, stat->expr, TRUE); 1520 if(FAILED(hres)) 1521 return hres; 1522 if(!push_instr(ctx, OP_setret)) 1523 return E_OUTOFMEMORY; 1524 } 1525 1526 hres = pop_to_stat(ctx, NULL); 1527 if(FAILED(hres)) 1528 return hres; 1529 1530 return push_instr_uint(ctx, OP_ret, !stat->expr); 1531 } 1532 1533 /* ECMA-262 3rd Edition 12.10 */ 1534 static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat) 1535 { 1536 statement_ctx_t stat_ctx = {0, TRUE, FALSE}; 1537 HRESULT hres; 1538 1539 hres = compile_expression(ctx, stat->expr, TRUE); 1540 if(FAILED(hres)) 1541 return hres; 1542 1543 if(!push_instr(ctx, OP_push_scope)) 1544 return E_OUTOFMEMORY; 1545 1546 hres = compile_statement(ctx, &stat_ctx, stat->statement); 1547 if(FAILED(hres)) 1548 return hres; 1549 1550 if(!push_instr(ctx, OP_pop_scope)) 1551 return E_OUTOFMEMORY; 1552 1553 return S_OK; 1554 } 1555 1556 /* ECMA-262 3rd Edition 12.10 */ 1557 static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat) 1558 { 1559 statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter; 1560 HRESULT hres; 1561 1562 for(iter = ctx->stat_ctx; iter; iter = iter->next) { 1563 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) { 1564 WARN("Label %s redefined\n", debugstr_w(stat->identifier)); 1565 return JS_E_LABEL_REDEFINED; 1566 } 1567 } 1568 1569 /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */ 1570 stat_ctx.break_label = alloc_label(ctx); 1571 if(!stat_ctx.break_label) 1572 return E_OUTOFMEMORY; 1573 1574 hres = compile_statement(ctx, &stat_ctx, stat->statement); 1575 if(FAILED(hres)) 1576 return hres; 1577 1578 label_set_addr(ctx, stat_ctx.break_label); 1579 return S_OK; 1580 } 1581 1582 /* ECMA-262 3rd Edition 12.13 */ 1583 static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat) 1584 { 1585 statement_ctx_t stat_ctx = {0, FALSE, FALSE}; 1586 unsigned case_cnt = 0, *case_jmps, i, default_jmp; 1587 BOOL have_default = FALSE; 1588 statement_t *stat_iter; 1589 case_clausule_t *iter; 1590 HRESULT hres; 1591 1592 hres = compile_expression(ctx, stat->expr, TRUE); 1593 if(FAILED(hres)) 1594 return hres; 1595 1596 stat_ctx.break_label = alloc_label(ctx); 1597 if(!stat_ctx.break_label) 1598 return E_OUTOFMEMORY; 1599 1600 for(iter = stat->case_list; iter; iter = iter->next) { 1601 if(iter->expr) 1602 case_cnt++; 1603 } 1604 1605 case_jmps = heap_alloc(case_cnt * sizeof(*case_jmps)); 1606 if(!case_jmps) 1607 return E_OUTOFMEMORY; 1608 1609 i = 0; 1610 for(iter = stat->case_list; iter; iter = iter->next) { 1611 if(!iter->expr) { 1612 have_default = TRUE; 1613 continue; 1614 } 1615 1616 hres = compile_expression(ctx, iter->expr, TRUE); 1617 if(FAILED(hres)) 1618 break; 1619 1620 case_jmps[i] = push_instr(ctx, OP_case); 1621 if(!case_jmps[i]) { 1622 hres = E_OUTOFMEMORY; 1623 break; 1624 } 1625 i++; 1626 } 1627 1628 if(SUCCEEDED(hres)) { 1629 hres = push_instr_uint(ctx, OP_pop, 1); 1630 if(SUCCEEDED(hres)) { 1631 default_jmp = push_instr(ctx, OP_jmp); 1632 if(!default_jmp) 1633 hres = E_OUTOFMEMORY; 1634 } 1635 } 1636 1637 if(FAILED(hres)) { 1638 heap_free(case_jmps); 1639 return hres; 1640 } 1641 1642 i = 0; 1643 for(iter = stat->case_list; iter; iter = iter->next) { 1644 while(iter->next && iter->next->stat == iter->stat) { 1645 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off); 1646 iter = iter->next; 1647 } 1648 1649 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off); 1650 1651 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter); 1652 stat_iter = stat_iter->next) { 1653 hres = compile_statement(ctx, &stat_ctx, stat_iter); 1654 if(FAILED(hres)) 1655 break; 1656 } 1657 if(FAILED(hres)) 1658 break; 1659 } 1660 1661 heap_free(case_jmps); 1662 if(FAILED(hres)) 1663 return hres; 1664 assert(i == case_cnt); 1665 1666 if(!have_default) { 1667 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label); 1668 if(FAILED(hres)) 1669 return hres; 1670 set_arg_uint(ctx, default_jmp, ctx->code_off); 1671 } 1672 1673 label_set_addr(ctx, stat_ctx.break_label); 1674 return S_OK; 1675 } 1676 1677 /* ECMA-262 3rd Edition 12.13 */ 1678 static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat) 1679 { 1680 HRESULT hres; 1681 1682 hres = compile_expression(ctx, stat->expr, TRUE); 1683 if(FAILED(hres)) 1684 return hres; 1685 1686 return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY; 1687 } 1688 1689 /* ECMA-262 3rd Edition 12.14 */ 1690 static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat) 1691 { 1692 statement_ctx_t try_ctx = {0, FALSE, TRUE}, finally_ctx = {2, FALSE, FALSE}; 1693 unsigned push_except, finally_off = 0, catch_off = 0, pop_except, catch_pop_except = 0; 1694 BSTR ident; 1695 HRESULT hres; 1696 1697 push_except = push_instr(ctx, OP_push_except); 1698 if(!push_except) 1699 return E_OUTOFMEMORY; 1700 1701 if(stat->catch_block) { 1702 ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier); 1703 if(!ident) 1704 return E_OUTOFMEMORY; 1705 }else { 1706 ident = NULL; 1707 } 1708 1709 hres = compile_statement(ctx, &try_ctx, stat->try_statement); 1710 if(FAILED(hres)) 1711 return hres; 1712 1713 pop_except = push_instr(ctx, OP_pop_except); 1714 if(!pop_except) 1715 return E_OUTOFMEMORY; 1716 1717 if(stat->catch_block) { 1718 statement_ctx_t catch_ctx = {0, TRUE, stat->finally_statement != NULL}; 1719 1720 if(stat->finally_statement) 1721 catch_ctx.using_except = TRUE; 1722 1723 catch_off = ctx->code_off; 1724 1725 hres = push_instr_bstr(ctx, OP_enter_catch, ident); 1726 if(FAILED(hres)) 1727 return hres; 1728 1729 hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement); 1730 if(FAILED(hres)) 1731 return hres; 1732 1733 if(!push_instr(ctx, OP_pop_scope)) 1734 return E_OUTOFMEMORY; 1735 1736 if(stat->finally_statement) { 1737 catch_pop_except = push_instr(ctx, OP_pop_except); 1738 if(!catch_pop_except) 1739 return E_OUTOFMEMORY; 1740 } 1741 } 1742 1743 if(stat->finally_statement) { 1744 /* 1745 * finally block expects two elements on the stack, which may be: 1746 * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address 1747 * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows 1748 */ 1749 finally_off = ctx->code_off; 1750 hres = compile_statement(ctx, &finally_ctx, stat->finally_statement); 1751 if(FAILED(hres)) 1752 return hres; 1753 1754 if(!push_instr(ctx, OP_end_finally)) 1755 return E_OUTOFMEMORY; 1756 } 1757 1758 instr_ptr(ctx, pop_except)->u.arg[0].uint = ctx->code_off; 1759 if(catch_pop_except) 1760 instr_ptr(ctx, catch_pop_except)->u.arg[0].uint = ctx->code_off; 1761 instr_ptr(ctx, push_except)->u.arg[0].uint = catch_off; 1762 instr_ptr(ctx, push_except)->u.arg[1].uint = finally_off; 1763 return S_OK; 1764 } 1765 1766 static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx, statement_t *stat) 1767 { 1768 HRESULT hres; 1769 1770 if(stat_ctx) { 1771 stat_ctx->next = ctx->stat_ctx; 1772 ctx->stat_ctx = stat_ctx; 1773 } 1774 1775 switch(stat->type) { 1776 case STAT_BLOCK: 1777 hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list); 1778 break; 1779 case STAT_BREAK: 1780 hres = compile_break_statement(ctx, (branch_statement_t*)stat); 1781 break; 1782 case STAT_CONTINUE: 1783 hres = compile_continue_statement(ctx, (branch_statement_t*)stat); 1784 break; 1785 case STAT_EMPTY: 1786 /* nothing to do */ 1787 hres = S_OK; 1788 break; 1789 case STAT_EXPR: 1790 hres = compile_expression_statement(ctx, (expression_statement_t*)stat); 1791 break; 1792 case STAT_FOR: 1793 hres = compile_for_statement(ctx, (for_statement_t*)stat); 1794 break; 1795 case STAT_FORIN: 1796 hres = compile_forin_statement(ctx, (forin_statement_t*)stat); 1797 break; 1798 case STAT_IF: 1799 hres = compile_if_statement(ctx, (if_statement_t*)stat); 1800 break; 1801 case STAT_LABEL: 1802 hres = compile_labelled_statement(ctx, (labelled_statement_t*)stat); 1803 break; 1804 case STAT_RETURN: 1805 hres = compile_return_statement(ctx, (expression_statement_t*)stat); 1806 break; 1807 case STAT_SWITCH: 1808 hres = compile_switch_statement(ctx, (switch_statement_t*)stat); 1809 break; 1810 case STAT_THROW: 1811 hres = compile_throw_statement(ctx, (expression_statement_t*)stat); 1812 break; 1813 case STAT_TRY: 1814 hres = compile_try_statement(ctx, (try_statement_t*)stat); 1815 break; 1816 case STAT_VAR: 1817 hres = compile_var_statement(ctx, (var_statement_t*)stat); 1818 break; 1819 case STAT_WHILE: 1820 hres = compile_while_statement(ctx, (while_statement_t*)stat); 1821 break; 1822 case STAT_WITH: 1823 hres = compile_with_statement(ctx, (with_statement_t*)stat); 1824 break; 1825 DEFAULT_UNREACHABLE; 1826 } 1827 1828 if(stat_ctx) { 1829 assert(ctx->stat_ctx == stat_ctx); 1830 ctx->stat_ctx = stat_ctx->next; 1831 } 1832 1833 return hres; 1834 } 1835 1836 static int function_local_cmp(const void *key, const struct wine_rb_entry *entry) 1837 { 1838 function_local_t *local = WINE_RB_ENTRY_VALUE(entry, function_local_t, entry); 1839 return wcscmp(key, local->name); 1840 } 1841 1842 static inline function_local_t *find_local(compiler_ctx_t *ctx, const WCHAR *name) 1843 { 1844 struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name); 1845 return entry ? WINE_RB_ENTRY_VALUE(entry, function_local_t, entry) : NULL; 1846 } 1847 1848 static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref) 1849 { 1850 function_local_t *local; 1851 1852 local = heap_pool_alloc(&ctx->heap, sizeof(*local)); 1853 if(!local) 1854 return FALSE; 1855 1856 local->name = name; 1857 local->ref = ref; 1858 wine_rb_put(&ctx->locals, name, &local->entry); 1859 ctx->locals_cnt++; 1860 return TRUE; 1861 } 1862 1863 static BOOL alloc_variable(compiler_ctx_t *ctx, const WCHAR *name) 1864 { 1865 BSTR ident; 1866 1867 if(find_local(ctx, name)) 1868 return TRUE; 1869 1870 ident = compiler_alloc_bstr(ctx, name); 1871 if(!ident) 1872 return FALSE; 1873 1874 return alloc_local(ctx, ident, ctx->func->var_cnt++); 1875 } 1876 1877 static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expression_t *expr) 1878 { 1879 expr->func_id = ctx->func->func_cnt++; 1880 ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr); 1881 1882 return !expr->identifier || expr->event_target || alloc_variable(ctx, expr->identifier) 1883 ? S_OK : E_OUTOFMEMORY; 1884 } 1885 1886 static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr) 1887 { 1888 HRESULT hres = S_OK; 1889 1890 switch(expr->type) { 1891 case EXPR_ADD: 1892 case EXPR_AND: 1893 case EXPR_ARRAY: 1894 case EXPR_ASSIGN: 1895 case EXPR_ASSIGNADD: 1896 case EXPR_ASSIGNAND: 1897 case EXPR_ASSIGNSUB: 1898 case EXPR_ASSIGNMUL: 1899 case EXPR_ASSIGNDIV: 1900 case EXPR_ASSIGNMOD: 1901 case EXPR_ASSIGNOR: 1902 case EXPR_ASSIGNLSHIFT: 1903 case EXPR_ASSIGNRSHIFT: 1904 case EXPR_ASSIGNRRSHIFT: 1905 case EXPR_ASSIGNXOR: 1906 case EXPR_BAND: 1907 case EXPR_BOR: 1908 case EXPR_COMMA: 1909 case EXPR_DIV: 1910 case EXPR_EQ: 1911 case EXPR_EQEQ: 1912 case EXPR_GREATER: 1913 case EXPR_GREATEREQ: 1914 case EXPR_IN: 1915 case EXPR_INSTANCEOF: 1916 case EXPR_LESS: 1917 case EXPR_LESSEQ: 1918 case EXPR_LSHIFT: 1919 case EXPR_MOD: 1920 case EXPR_MUL: 1921 case EXPR_NOTEQ: 1922 case EXPR_NOTEQEQ: 1923 case EXPR_OR: 1924 case EXPR_RSHIFT: 1925 case EXPR_RRSHIFT: 1926 case EXPR_SUB: 1927 case EXPR_BXOR: { 1928 binary_expression_t *binary_expr = (binary_expression_t*)expr; 1929 1930 hres = visit_expression(ctx, binary_expr->expression1); 1931 if(FAILED(hres)) 1932 return hres; 1933 1934 hres = visit_expression(ctx, binary_expr->expression2); 1935 break; 1936 } 1937 case EXPR_BITNEG: 1938 case EXPR_DELETE: 1939 case EXPR_LOGNEG: 1940 case EXPR_MINUS: 1941 case EXPR_PLUS: 1942 case EXPR_POSTDEC: 1943 case EXPR_POSTINC: 1944 case EXPR_PREDEC: 1945 case EXPR_PREINC: 1946 case EXPR_TYPEOF: 1947 case EXPR_VOID: 1948 hres = visit_expression(ctx, ((unary_expression_t*)expr)->expression); 1949 break; 1950 case EXPR_IDENT: 1951 case EXPR_LITERAL: 1952 case EXPR_THIS: 1953 break; 1954 case EXPR_ARRAYLIT: { 1955 array_literal_expression_t *array_expr = (array_literal_expression_t*)expr; 1956 array_element_t *iter; 1957 1958 for(iter = array_expr->element_list; iter; iter = iter->next) { 1959 hres = visit_expression(ctx, iter->expr); 1960 if(FAILED(hres)) 1961 return hres; 1962 } 1963 break; 1964 } 1965 case EXPR_CALL: 1966 case EXPR_NEW: { 1967 call_expression_t *call_expr = (call_expression_t*)expr; 1968 argument_t *arg; 1969 1970 hres = visit_expression(ctx, call_expr->expression); 1971 if(FAILED(hres)) 1972 return hres; 1973 1974 for(arg = call_expr->argument_list; arg; arg = arg->next) { 1975 hres = visit_expression(ctx, arg->expr); 1976 if(FAILED(hres)) 1977 return hres; 1978 } 1979 break; 1980 } 1981 case EXPR_COND: { 1982 conditional_expression_t *cond_expr = (conditional_expression_t*)expr; 1983 1984 hres = visit_expression(ctx, cond_expr->expression); 1985 if(FAILED(hres)) 1986 return hres; 1987 1988 hres = visit_expression(ctx, cond_expr->true_expression); 1989 if(FAILED(hres)) 1990 return hres; 1991 1992 hres = visit_expression(ctx, cond_expr->false_expression); 1993 break; 1994 } 1995 case EXPR_FUNC: 1996 hres = visit_function_expression(ctx, (function_expression_t*)expr); 1997 break; 1998 case EXPR_MEMBER: 1999 hres = visit_expression(ctx, ((member_expression_t*)expr)->expression); 2000 break; 2001 case EXPR_PROPVAL: { 2002 property_definition_t *iter; 2003 for(iter = ((property_value_expression_t*)expr)->property_list; iter; iter = iter->next) { 2004 hres = visit_expression(ctx, iter->value); 2005 if(FAILED(hres)) 2006 return hres; 2007 } 2008 break; 2009 } 2010 DEFAULT_UNREACHABLE; 2011 } 2012 2013 return hres; 2014 } 2015 2016 static HRESULT visit_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list) 2017 { 2018 variable_declaration_t *iter; 2019 HRESULT hres; 2020 2021 for(iter = list; iter; iter = iter->next) { 2022 if(!alloc_variable(ctx, iter->identifier)) 2023 return E_OUTOFMEMORY; 2024 2025 if(iter->expr) { 2026 hres = visit_expression(ctx, iter->expr); 2027 if(FAILED(hres)) 2028 return hres; 2029 } 2030 } 2031 2032 return S_OK; 2033 } 2034 2035 static HRESULT visit_statement(compiler_ctx_t*,statement_t*); 2036 2037 static HRESULT visit_block_statement(compiler_ctx_t *ctx, statement_t *iter) 2038 { 2039 HRESULT hres; 2040 2041 while(iter) { 2042 hres = visit_statement(ctx, iter); 2043 if(FAILED(hres)) 2044 return hres; 2045 2046 iter = iter->next; 2047 } 2048 2049 return S_OK; 2050 } 2051 2052 static HRESULT visit_statement(compiler_ctx_t *ctx, statement_t *stat) 2053 { 2054 HRESULT hres = S_OK; 2055 2056 switch(stat->type) { 2057 case STAT_BLOCK: 2058 hres = visit_block_statement(ctx, ((block_statement_t*)stat)->stat_list); 2059 break; 2060 case STAT_BREAK: 2061 case STAT_CONTINUE: 2062 case STAT_EMPTY: 2063 break; 2064 case STAT_EXPR: 2065 case STAT_RETURN: 2066 case STAT_THROW: { 2067 expression_statement_t *expr_stat = (expression_statement_t*)stat; 2068 if(expr_stat->expr) 2069 hres = visit_expression(ctx, expr_stat->expr); 2070 break; 2071 } 2072 case STAT_FOR: { 2073 for_statement_t *for_stat = (for_statement_t*)stat; 2074 2075 if(for_stat->variable_list) 2076 hres = visit_variable_list(ctx, for_stat->variable_list); 2077 else if(for_stat->begin_expr) 2078 hres = visit_expression(ctx, for_stat->begin_expr); 2079 if(FAILED(hres)) 2080 break; 2081 2082 if(for_stat->expr) { 2083 hres = visit_expression(ctx, for_stat->expr); 2084 if(FAILED(hres)) 2085 break; 2086 } 2087 2088 hres = visit_statement(ctx, for_stat->statement); 2089 if(FAILED(hres)) 2090 break; 2091 2092 if(for_stat->end_expr) 2093 hres = visit_expression(ctx, for_stat->end_expr); 2094 break; 2095 } 2096 case STAT_FORIN: { 2097 forin_statement_t *forin_stat = (forin_statement_t*)stat; 2098 2099 if(forin_stat->variable) { 2100 hres = visit_variable_list(ctx, forin_stat->variable); 2101 if(FAILED(hres)) 2102 break; 2103 } 2104 2105 hres = visit_expression(ctx, forin_stat->in_expr); 2106 if(FAILED(hres)) 2107 return hres; 2108 2109 if(forin_stat->expr) { 2110 hres = visit_expression(ctx, forin_stat->expr); 2111 if(FAILED(hres)) 2112 return hres; 2113 } 2114 2115 hres = visit_statement(ctx, forin_stat->statement); 2116 break; 2117 } 2118 case STAT_IF: { 2119 if_statement_t *if_stat = (if_statement_t*)stat; 2120 2121 hres = visit_expression(ctx, if_stat->expr); 2122 if(FAILED(hres)) 2123 return hres; 2124 2125 hres = visit_statement(ctx, if_stat->if_stat); 2126 if(FAILED(hres)) 2127 return hres; 2128 2129 if(if_stat->else_stat) 2130 hres = visit_statement(ctx, if_stat->else_stat); 2131 break; 2132 } 2133 case STAT_LABEL: 2134 hres = visit_statement(ctx, ((labelled_statement_t*)stat)->statement); 2135 break; 2136 case STAT_SWITCH: { 2137 switch_statement_t *switch_stat = (switch_statement_t*)stat; 2138 statement_t *stat_iter; 2139 case_clausule_t *iter; 2140 2141 hres = visit_expression(ctx, switch_stat->expr); 2142 if(FAILED(hres)) 2143 return hres; 2144 2145 for(iter = switch_stat->case_list; iter; iter = iter->next) { 2146 if(!iter->expr) 2147 continue; 2148 hres = visit_expression(ctx, iter->expr); 2149 if(FAILED(hres)) 2150 return hres; 2151 } 2152 2153 for(iter = switch_stat->case_list; iter; iter = iter->next) { 2154 while(iter->next && iter->next->stat == iter->stat) 2155 iter = iter->next; 2156 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter); 2157 stat_iter = stat_iter->next) { 2158 hres = visit_statement(ctx, stat_iter); 2159 if(FAILED(hres)) 2160 return hres; 2161 } 2162 } 2163 break; 2164 } 2165 case STAT_TRY: { 2166 try_statement_t *try_stat = (try_statement_t*)stat; 2167 2168 hres = visit_statement(ctx, try_stat->try_statement); 2169 if(FAILED(hres)) 2170 return hres; 2171 2172 if(try_stat->catch_block) { 2173 hres = visit_statement(ctx, try_stat->catch_block->statement); 2174 if(FAILED(hres)) 2175 return hres; 2176 } 2177 2178 if(try_stat->finally_statement) 2179 hres = visit_statement(ctx, try_stat->finally_statement); 2180 break; 2181 } 2182 case STAT_VAR: 2183 hres = visit_variable_list(ctx, ((var_statement_t*)stat)->variable_list); 2184 break; 2185 case STAT_WHILE: { 2186 while_statement_t *while_stat = (while_statement_t*)stat; 2187 2188 hres = visit_expression(ctx, while_stat->expr); 2189 if(FAILED(hres)) 2190 return hres; 2191 2192 hres = visit_statement(ctx, while_stat->statement); 2193 break; 2194 } 2195 case STAT_WITH: { 2196 with_statement_t *with_stat = (with_statement_t*)stat; 2197 2198 hres = visit_expression(ctx, with_stat->expr); 2199 if(FAILED(hres)) 2200 return hres; 2201 2202 hres = visit_statement(ctx, with_stat->statement); 2203 break; 2204 } 2205 DEFAULT_UNREACHABLE; 2206 } 2207 2208 return hres; 2209 } 2210 2211 static void resolve_labels(compiler_ctx_t *ctx, unsigned off) 2212 { 2213 instr_t *instr; 2214 2215 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) { 2216 if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->u.arg->uint & LABEL_FLAG)) { 2217 assert((instr->u.arg->uint & ~LABEL_FLAG) < ctx->labels_cnt); 2218 instr->u.arg->uint = ctx->labels[instr->u.arg->uint & ~LABEL_FLAG]; 2219 } 2220 assert(instr_info[instr->op].arg2_type != ARG_ADDR); 2221 } 2222 2223 ctx->labels_cnt = 0; 2224 } 2225 2226 void release_bytecode(bytecode_t *code) 2227 { 2228 unsigned i; 2229 2230 if(--code->ref) 2231 return; 2232 2233 for(i=0; i < code->bstr_cnt; i++) 2234 SysFreeString(code->bstr_pool[i]); 2235 for(i=0; i < code->str_cnt; i++) 2236 jsstr_release(code->str_pool[i]); 2237 2238 heap_free(code->source); 2239 heap_pool_free(&code->heap); 2240 heap_free(code->bstr_pool); 2241 heap_free(code->str_pool); 2242 heap_free(code->instrs); 2243 heap_free(code); 2244 } 2245 2246 static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source) 2247 { 2248 compiler->code = heap_alloc_zero(sizeof(bytecode_t)); 2249 if(!compiler->code) 2250 return E_OUTOFMEMORY; 2251 2252 compiler->code->ref = 1; 2253 heap_pool_init(&compiler->code->heap); 2254 2255 compiler->code->source = heap_strdupW(source); 2256 if(!compiler->code->source) { 2257 release_bytecode(compiler->code); 2258 return E_OUTOFMEMORY; 2259 } 2260 2261 compiler->code->instrs = heap_alloc(64 * sizeof(instr_t)); 2262 if(!compiler->code->instrs) { 2263 release_bytecode(compiler->code); 2264 return E_OUTOFMEMORY; 2265 } 2266 2267 compiler->code_size = 64; 2268 compiler->code_off = 1; 2269 return S_OK; 2270 } 2271 2272 static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, function_expression_t *func_expr, 2273 BOOL from_eval, function_code_t *func) 2274 { 2275 function_expression_t *iter; 2276 function_local_t *local; 2277 unsigned off, i; 2278 HRESULT hres; 2279 2280 TRACE("\n"); 2281 2282 ctx->func_head = ctx->func_tail = NULL; 2283 ctx->from_eval = from_eval; 2284 ctx->func = func; 2285 ctx->locals_cnt = 0; 2286 wine_rb_init(&ctx->locals, function_local_cmp); 2287 2288 if(func_expr) { 2289 parameter_t *param_iter; 2290 2291 if(func_expr->identifier) { 2292 func->name = compiler_alloc_bstr(ctx, func_expr->identifier); 2293 if(!func->name) 2294 return E_OUTOFMEMORY; 2295 } 2296 2297 if(func_expr->event_target) { 2298 func->event_target = compiler_alloc_bstr(ctx, func_expr->event_target); 2299 if(!func->event_target) 2300 return E_OUTOFMEMORY; 2301 } 2302 2303 func->source = func_expr->src_str; 2304 func->source_len = func_expr->src_len; 2305 2306 for(param_iter = func_expr->parameter_list; param_iter; param_iter = param_iter->next) 2307 func->param_cnt++; 2308 2309 func->params = compiler_alloc(ctx->code, func->param_cnt * sizeof(*func->params)); 2310 if(!func->params) 2311 return E_OUTOFMEMORY; 2312 2313 for(param_iter = func_expr->parameter_list, i=0; param_iter; param_iter = param_iter->next, i++) { 2314 func->params[i] = compiler_alloc_bstr(ctx, param_iter->identifier); 2315 if(!func->params[i]) 2316 return E_OUTOFMEMORY; 2317 } 2318 } 2319 2320 for(i = 0; i < func->param_cnt; i++) { 2321 if(!find_local(ctx, func->params[i]) && !alloc_local(ctx, func->params[i], -i-1)) 2322 return E_OUTOFMEMORY; 2323 } 2324 2325 hres = visit_block_statement(ctx, source->statement); 2326 if(FAILED(hres)) 2327 return hres; 2328 2329 func->locals = compiler_alloc(ctx->code, ctx->locals_cnt * sizeof(*func->locals)); 2330 if(!func->locals) 2331 return E_OUTOFMEMORY; 2332 func->locals_cnt = ctx->locals_cnt; 2333 2334 func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables)); 2335 if(!func->variables) 2336 return E_OUTOFMEMORY; 2337 2338 i = 0; 2339 WINE_RB_FOR_EACH_ENTRY(local, &ctx->locals, function_local_t, entry) { 2340 func->locals[i].name = local->name; 2341 func->locals[i].ref = local->ref; 2342 if(local->ref >= 0) { 2343 func->variables[local->ref].name = local->name; 2344 func->variables[local->ref].func_id = -1; 2345 } 2346 i++; 2347 } 2348 assert(i == ctx->locals_cnt); 2349 2350 func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs)); 2351 if(!func->funcs) 2352 return E_OUTOFMEMORY; 2353 memset(func->funcs, 0, func->func_cnt * sizeof(*func->funcs)); 2354 2355 off = ctx->code_off; 2356 hres = compile_block_statement(ctx, source->statement); 2357 if(FAILED(hres)) 2358 return hres; 2359 2360 resolve_labels(ctx, off); 2361 2362 hres = push_instr_uint(ctx, OP_ret, !from_eval); 2363 if(FAILED(hres)) 2364 return hres; 2365 2366 if(TRACE_ON(jscript_disas)) 2367 dump_code(ctx, off); 2368 2369 func->instr_off = off; 2370 2371 for(iter = ctx->func_head, i=0; iter; iter = iter->next, i++) { 2372 hres = compile_function(ctx, iter->source_elements, iter, FALSE, func->funcs+i); 2373 if(FAILED(hres)) 2374 return hres; 2375 2376 TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name)); 2377 if(func->funcs[i].name && !func->funcs[i].event_target) { 2378 local_ref_t *local_ref = lookup_local(func, func->funcs[i].name); 2379 func->funcs[i].local_ref = local_ref->ref; 2380 TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name)); 2381 if(local_ref->ref >= 0) 2382 func->variables[local_ref->ref].func_id = i; 2383 } 2384 } 2385 2386 assert(i == func->func_cnt); 2387 2388 return S_OK; 2389 } 2390 2391 static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size) 2392 { 2393 const WCHAR *ptr = args, *ptr2; 2394 unsigned arg_cnt = 0; 2395 2396 while(iswspace(*ptr)) 2397 ptr++; 2398 if(!*ptr) { 2399 if(args_size) 2400 *args_size = 0; 2401 return S_OK; 2402 } 2403 2404 while(1) { 2405 if(!iswalpha(*ptr) && *ptr != '_') { 2406 FIXME("expected alpha or '_': %s\n", debugstr_w(ptr)); 2407 return E_FAIL; 2408 } 2409 2410 ptr2 = ptr; 2411 while(iswalnum(*ptr) || *ptr == '_') 2412 ptr++; 2413 2414 if(*ptr && *ptr != ',' && !iswspace(*ptr)) { 2415 FIXME("unexpected har %s\n", debugstr_w(ptr)); 2416 return E_FAIL; 2417 } 2418 2419 if(arg_array) { 2420 arg_array[arg_cnt] = compiler_alloc_bstr_len(ctx, ptr2, ptr-ptr2); 2421 if(!arg_array[arg_cnt]) 2422 return E_OUTOFMEMORY; 2423 } 2424 arg_cnt++; 2425 2426 while(iswspace(*ptr)) 2427 ptr++; 2428 if(!*ptr) 2429 break; 2430 if(*ptr != ',') { 2431 FIXME("expected ',': %s\n", debugstr_w(ptr)); 2432 return E_FAIL; 2433 } 2434 2435 ptr++; 2436 while(iswspace(*ptr)) 2437 ptr++; 2438 } 2439 2440 if(args_size) 2441 *args_size = arg_cnt; 2442 return S_OK; 2443 } 2444 2445 static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args) 2446 { 2447 HRESULT hres; 2448 2449 hres = parse_arguments(ctx, args, NULL, &ctx->code->global_code.param_cnt); 2450 if(FAILED(hres)) 2451 return hres; 2452 2453 ctx->code->global_code.params = compiler_alloc(ctx->code, 2454 ctx->code->global_code.param_cnt * sizeof(*ctx->code->global_code.params)); 2455 if(!ctx->code->global_code.params) 2456 return E_OUTOFMEMORY; 2457 2458 return parse_arguments(ctx, args, ctx->code->global_code.params, NULL); 2459 } 2460 2461 HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter, 2462 BOOL from_eval, BOOL use_decode, bytecode_t **ret) 2463 { 2464 compiler_ctx_t compiler = {0}; 2465 HRESULT hres; 2466 2467 hres = init_code(&compiler, code); 2468 if(FAILED(hres)) 2469 return hres; 2470 2471 if(args) { 2472 hres = compile_arguments(&compiler, args); 2473 if(FAILED(hres)) 2474 return hres; 2475 } 2476 2477 if(use_decode) { 2478 hres = decode_source(compiler.code->source); 2479 if(FAILED(hres)) { 2480 WARN("Decoding failed\n"); 2481 return hres; 2482 } 2483 } 2484 2485 hres = script_parse(ctx, &compiler, compiler.code->source, delimiter, from_eval, &compiler.parser); 2486 if(FAILED(hres)) { 2487 release_bytecode(compiler.code); 2488 return hres; 2489 } 2490 2491 heap_pool_init(&compiler.heap); 2492 hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code); 2493 heap_pool_free(&compiler.heap); 2494 parser_release(compiler.parser); 2495 if(FAILED(hres)) { 2496 release_bytecode(compiler.code); 2497 return hres; 2498 } 2499 2500 *ret = compiler.code; 2501 return S_OK; 2502 } 2503