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