2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
28 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas
);
30 typedef struct _statement_ctx_t
{
36 unsigned continue_label
;
38 struct _statement_ctx_t
*next
;
41 struct _compiler_ctx_t
{
52 statement_ctx_t
*stat_ctx
;
57 instr_arg_type_t arg1_type
;
58 instr_arg_type_t arg2_type
;
60 #define X(n,a,b,c) {#n,b,c},
65 static void dump_instr_arg(instr_arg_type_t type
, instr_arg_t
*arg
)
69 TRACE_(jscript_disas
)("\t%s", debugstr_w(arg
->str
));
72 TRACE_(jscript_disas
)("\t%s", debugstr_wn(arg
->bstr
, SysStringLen(arg
->bstr
)));
75 TRACE_(jscript_disas
)("\t%d", arg
->uint
);
79 TRACE_(jscript_disas
)("\t%u", arg
->uint
);
82 TRACE_(jscript_disas
)("\t%lf", *arg
->dbl
);
93 static void dump_code(compiler_ctx_t
*ctx
, unsigned off
)
97 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
98 TRACE_(jscript_disas
)("%d:\t%s", (int)(instr
-ctx
->code
->instrs
), instr_info
[instr
->op
].op_str
);
99 dump_instr_arg(instr_info
[instr
->op
].arg1_type
, &instr
->arg1
);
100 dump_instr_arg(instr_info
[instr
->op
].arg2_type
, &instr
->arg2
);
101 TRACE_(jscript_disas
)("\n");
105 static HRESULT
compile_expression(compiler_ctx_t
*,expression_t
*);
106 static HRESULT
compile_statement(compiler_ctx_t
*,statement_ctx_t
*,statement_t
*);
108 static inline void *compiler_alloc(bytecode_t
*code
, size_t size
)
110 return jsheap_alloc(&code
->heap
, size
);
113 static WCHAR
*compiler_alloc_string(bytecode_t
*code
, const WCHAR
*str
)
118 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
119 ret
= compiler_alloc(code
, size
);
121 memcpy(ret
, str
, size
);
125 static BSTR
compiler_alloc_bstr(compiler_ctx_t
*ctx
, const WCHAR
*str
)
127 if(!ctx
->code
->bstr_pool_size
) {
128 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
129 if(!ctx
->code
->bstr_pool
)
131 ctx
->code
->bstr_pool_size
= 8;
132 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
135 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
139 ctx
->code
->bstr_pool
= new_pool
;
140 ctx
->code
->bstr_pool_size
*= 2;
143 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
144 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
147 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
150 static unsigned push_instr(compiler_ctx_t
*ctx
, jsop_t op
)
152 assert(ctx
->code_size
>= ctx
->code_off
);
154 if(!ctx
->code_size
) {
155 ctx
->code
->instrs
= heap_alloc(64 * sizeof(instr_t
));
156 if(!ctx
->code
->instrs
)
159 }else if(ctx
->code_size
== ctx
->code_off
) {
162 new_instrs
= heap_realloc(ctx
->code
->instrs
, ctx
->code_size
*2*sizeof(instr_t
));
166 ctx
->code
->instrs
= new_instrs
;
170 ctx
->code
->instrs
[ctx
->code_off
].op
= op
;
171 return ctx
->code_off
++;
174 static inline instr_t
*instr_ptr(compiler_ctx_t
*ctx
, unsigned off
)
176 assert(off
< ctx
->code_off
);
177 return ctx
->code
->instrs
+ off
;
180 static HRESULT
push_instr_int(compiler_ctx_t
*ctx
, jsop_t op
, LONG arg
)
184 instr
= push_instr(ctx
, op
);
186 return E_OUTOFMEMORY
;
188 instr_ptr(ctx
, instr
)->arg1
.lng
= arg
;
192 static HRESULT
push_instr_str(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
197 str
= compiler_alloc_string(ctx
->code
, arg
);
199 return E_OUTOFMEMORY
;
201 instr
= push_instr(ctx
, op
);
203 return E_OUTOFMEMORY
;
205 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
209 static HRESULT
push_instr_bstr(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
214 str
= compiler_alloc_bstr(ctx
, arg
);
216 return E_OUTOFMEMORY
;
218 instr
= push_instr(ctx
, op
);
220 return E_OUTOFMEMORY
;
222 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
226 static HRESULT
push_instr_bstr_uint(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
231 str
= compiler_alloc_bstr(ctx
, arg1
);
233 return E_OUTOFMEMORY
;
235 instr
= push_instr(ctx
, op
);
237 return E_OUTOFMEMORY
;
239 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
240 instr_ptr(ctx
, instr
)->arg2
.uint
= arg2
;
244 static HRESULT
push_instr_uint_str(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
249 str
= compiler_alloc_string(ctx
->code
, arg2
);
251 return E_OUTOFMEMORY
;
253 instr
= push_instr(ctx
, op
);
255 return E_OUTOFMEMORY
;
257 instr_ptr(ctx
, instr
)->arg1
.uint
= arg1
;
258 instr_ptr(ctx
, instr
)->arg2
.str
= str
;
262 static HRESULT
push_instr_double(compiler_ctx_t
*ctx
, jsop_t op
, double arg
)
267 dbl
= compiler_alloc(ctx
->code
, sizeof(arg
));
269 return E_OUTOFMEMORY
;
272 instr
= push_instr(ctx
, op
);
274 return E_OUTOFMEMORY
;
276 instr_ptr(ctx
, instr
)->arg1
.dbl
= dbl
;
280 static HRESULT
push_instr_uint(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg
)
284 instr
= push_instr(ctx
, op
);
286 return E_OUTOFMEMORY
;
288 instr_ptr(ctx
, instr
)->arg1
.uint
= arg
;
292 static HRESULT
compile_binary_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
296 hres
= compile_expression(ctx
, expr
->expression1
);
300 hres
= compile_expression(ctx
, expr
->expression2
);
304 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
307 static HRESULT
compile_unary_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
)
311 hres
= compile_expression(ctx
, expr
->expression
);
315 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
318 /* ECMA-262 3rd Edition 11.2.1 */
319 static HRESULT
compile_member_expression(compiler_ctx_t
*ctx
, member_expression_t
*expr
)
323 hres
= compile_expression(ctx
, expr
->expression
);
327 return push_instr_bstr(ctx
, OP_member
, expr
->identifier
);
330 #define LABEL_FLAG 0x80000000
332 static unsigned alloc_label(compiler_ctx_t
*ctx
)
334 if(!ctx
->labels_size
) {
335 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
338 ctx
->labels_size
= 8;
339 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
340 unsigned *new_labels
;
342 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
346 ctx
->labels
= new_labels
;
347 ctx
->labels_size
*= 2;
350 return ctx
->labels_cnt
++ | LABEL_FLAG
;
353 static void label_set_addr(compiler_ctx_t
*ctx
, unsigned label
)
355 assert(label
& LABEL_FLAG
);
356 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->code_off
;
359 static inline BOOL
is_memberid_expr(expression_type_t type
)
361 return type
== EXPR_IDENT
|| type
== EXPR_MEMBER
|| type
== EXPR_ARRAY
;
364 static HRESULT
compile_memberid_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, unsigned flags
)
370 identifier_expression_t
*ident_expr
= (identifier_expression_t
*)expr
;
372 hres
= push_instr_bstr_uint(ctx
, OP_identid
, ident_expr
->identifier
, flags
);
376 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
;
378 hres
= compile_expression(ctx
, array_expr
->expression1
);
382 hres
= compile_expression(ctx
, array_expr
->expression2
);
386 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
390 member_expression_t
*member_expr
= (member_expression_t
*)expr
;
392 hres
= compile_expression(ctx
, member_expr
->expression
);
396 /* FIXME: Potential optimization */
397 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
401 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
411 static HRESULT
compile_increment_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
, int n
)
415 if(!is_memberid_expr(expr
->expression
->type
)) {
416 hres
= compile_expression(ctx
, expr
->expression
);
420 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
423 hres
= compile_memberid_expression(ctx
, expr
->expression
, fdexNameEnsure
);
427 return push_instr_int(ctx
, op
, n
);
430 /* ECMA-262 3rd Edition 11.14 */
431 static HRESULT
compile_comma_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
)
435 hres
= compile_expression(ctx
, expr
->expression1
);
439 if(push_instr(ctx
, OP_pop
) == -1)
440 return E_OUTOFMEMORY
;
442 return compile_expression(ctx
, expr
->expression2
);
445 /* ECMA-262 3rd Edition 11.11 */
446 static HRESULT
compile_logical_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
451 hres
= compile_expression(ctx
, expr
->expression1
);
455 instr
= push_instr(ctx
, op
);
457 return E_OUTOFMEMORY
;
459 hres
= compile_expression(ctx
, expr
->expression2
);
463 instr_ptr(ctx
, instr
)->arg1
.uint
= ctx
->code_off
;
467 /* ECMA-262 3rd Edition 11.12 */
468 static HRESULT
compile_conditional_expression(compiler_ctx_t
*ctx
, conditional_expression_t
*expr
)
470 unsigned jmp_false
, jmp_end
;
473 hres
= compile_expression(ctx
, expr
->expression
);
477 jmp_false
= push_instr(ctx
, OP_cnd_z
);
479 return E_OUTOFMEMORY
;
481 hres
= compile_expression(ctx
, expr
->true_expression
);
485 jmp_end
= push_instr(ctx
, OP_jmp
);
487 return E_OUTOFMEMORY
;
489 instr_ptr(ctx
, jmp_false
)->arg1
.uint
= ctx
->code_off
;
490 if(push_instr(ctx
, OP_pop
) == -1)
491 return E_OUTOFMEMORY
;
493 hres
= compile_expression(ctx
, expr
->false_expression
);
497 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->code_off
;
501 static HRESULT
compile_new_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
)
503 unsigned arg_cnt
= 0;
507 hres
= compile_expression(ctx
, expr
->expression
);
511 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
512 hres
= compile_expression(ctx
, arg
->expr
);
518 return push_instr_int(ctx
, OP_new
, arg_cnt
);
521 static HRESULT
compile_interp_fallback(compiler_ctx_t
*ctx
, statement_t
*stat
)
525 instr
= push_instr(ctx
, OP_tree
);
527 return E_OUTOFMEMORY
;
529 instr_ptr(ctx
, instr
)->arg1
.stat
= stat
;
533 static HRESULT
compile_call_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
, BOOL
*no_ret
)
535 unsigned arg_cnt
= 0;
541 if(is_memberid_expr(expr
->expression
->type
)) {
543 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
546 hres
= compile_expression(ctx
, expr
->expression
);
552 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
553 hres
= compile_expression(ctx
, arg
->expr
);
559 instr
= push_instr(ctx
, op
);
561 return E_OUTOFMEMORY
;
563 instr_ptr(ctx
, instr
)->arg1
.uint
= arg_cnt
;
564 instr_ptr(ctx
, instr
)->arg2
.lng
= no_ret
== NULL
;
570 static HRESULT
compile_delete_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
574 switch(expr
->expression
->type
) {
576 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
->expression
;
578 hres
= compile_expression(ctx
, array_expr
->expression1
);
582 hres
= compile_expression(ctx
, array_expr
->expression2
);
586 if(push_instr(ctx
, OP_delete
) == -1)
587 return E_OUTOFMEMORY
;
591 member_expression_t
*member_expr
= (member_expression_t
*)expr
->expression
;
593 hres
= compile_expression(ctx
, member_expr
->expression
);
597 /* FIXME: Potential optimization */
598 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
602 if(push_instr(ctx
, OP_delete
) == -1)
603 return E_OUTOFMEMORY
;
607 return push_instr_bstr(ctx
, OP_delete_ident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
609 const WCHAR fixmeW
[] = {'F','I','X','M','E',0};
611 WARN("invalid delete, unimplemented exception message\n");
613 hres
= compile_expression(ctx
, expr
->expression
);
617 return push_instr_uint_str(ctx
, OP_throw_type
, JS_E_INVALID_DELETE
, fixmeW
);
624 static HRESULT
compile_assign_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
628 if(!is_memberid_expr(expr
->expression1
->type
)) {
629 hres
= compile_expression(ctx
, expr
->expression1
);
633 hres
= compile_expression(ctx
, expr
->expression2
);
637 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
638 return E_OUTOFMEMORY
;
640 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
643 hres
= compile_memberid_expression(ctx
, expr
->expression1
, fdexNameEnsure
);
647 if(op
!= OP_LAST
&& push_instr(ctx
, OP_refval
) == -1)
648 return E_OUTOFMEMORY
;
650 hres
= compile_expression(ctx
, expr
->expression2
);
654 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
655 return E_OUTOFMEMORY
;
657 if(push_instr(ctx
, OP_assign
) == -1)
658 return E_OUTOFMEMORY
;
663 static HRESULT
compile_typeof_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
668 if(is_memberid_expr(expr
->expression
->type
)) {
669 if(expr
->expression
->type
== EXPR_IDENT
)
670 return push_instr_str(ctx
, OP_typeofident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
673 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
676 hres
= compile_expression(ctx
, expr
->expression
);
681 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
684 static HRESULT
compile_literal(compiler_ctx_t
*ctx
, literal_t
*literal
)
686 switch(literal
->type
) {
688 return push_instr_int(ctx
, OP_bool
, literal
->u
.bval
);
690 return push_instr_double(ctx
, OP_double
, literal
->u
.dval
);
692 return push_instr_int(ctx
, OP_int
, literal
->u
.lval
);
694 return push_instr(ctx
, OP_null
);
696 return push_instr_str(ctx
, OP_str
, literal
->u
.wstr
);
701 str
= compiler_alloc(ctx
->code
, (literal
->u
.regexp
.str_len
+1)*sizeof(WCHAR
));
703 return E_OUTOFMEMORY
;
704 memcpy(str
, literal
->u
.regexp
.str
, literal
->u
.regexp
.str_len
*sizeof(WCHAR
));
705 str
[literal
->u
.regexp
.str_len
] = 0;
707 instr
= push_instr(ctx
, OP_regexp
);
709 return E_OUTOFMEMORY
;
711 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
712 instr_ptr(ctx
, instr
)->arg2
.lng
= literal
->u
.regexp
.flags
;
720 static HRESULT
literal_as_bstr(compiler_ctx_t
*ctx
, literal_t
*literal
, BSTR
*str
)
722 switch(literal
->type
) {
724 *str
= compiler_alloc_bstr(ctx
, literal
->u
.wstr
);
727 *str
= int_to_bstr(literal
->u
.lval
);
730 return double_to_bstr(literal
->u
.dval
, str
);
735 return *str
? S_OK
: E_OUTOFMEMORY
;
738 static HRESULT
compile_array_literal(compiler_ctx_t
*ctx
, array_literal_expression_t
*expr
)
740 unsigned i
, elem_cnt
= expr
->length
;
741 array_element_t
*iter
;
744 for(iter
= expr
->element_list
; iter
; iter
= iter
->next
) {
745 elem_cnt
+= iter
->elision
+1;
747 for(i
=0; i
< iter
->elision
; i
++) {
748 if(push_instr(ctx
, OP_undefined
) == -1)
749 return E_OUTOFMEMORY
;
752 hres
= compile_expression(ctx
, iter
->expr
);
757 for(i
=0; i
< expr
->length
; i
++) {
758 if(push_instr(ctx
, OP_undefined
) == -1)
759 return E_OUTOFMEMORY
;
762 return push_instr_uint(ctx
, OP_carray
, elem_cnt
);
765 static HRESULT
compile_object_literal(compiler_ctx_t
*ctx
, property_value_expression_t
*expr
)
772 if(push_instr(ctx
, OP_new_obj
) == -1)
773 return E_OUTOFMEMORY
;
775 for(iter
= expr
->property_list
; iter
; iter
= iter
->next
) {
776 hres
= literal_as_bstr(ctx
, iter
->name
, &name
);
780 hres
= compile_expression(ctx
, iter
->value
);
784 instr
= push_instr(ctx
, OP_obj_prop
);
786 return E_OUTOFMEMORY
;
788 instr_ptr(ctx
, instr
)->arg1
.bstr
= name
;
794 static HRESULT
compile_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
)
798 /* FIXME: not exactly right */
800 return push_instr_bstr(ctx
, OP_ident
, expr
->identifier
);
802 instr
= push_instr(ctx
, OP_func
);
804 return E_OUTOFMEMORY
;
806 instr_ptr(ctx
, instr
)->arg1
.func
= expr
;
810 static HRESULT
compile_expression_noret(compiler_ctx_t
*ctx
, expression_t
*expr
, BOOL
*no_ret
)
814 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
816 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_z
);
818 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_array
);
820 return compile_array_literal(ctx
, (array_literal_expression_t
*)expr
);
822 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_LAST
);
824 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
826 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
828 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
830 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
832 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
834 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
836 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
837 case EXPR_ASSIGNLSHIFT
:
838 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
839 case EXPR_ASSIGNRSHIFT
:
840 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
841 case EXPR_ASSIGNRRSHIFT
:
842 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
844 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
846 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
848 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_bneg
);
850 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
852 return compile_call_expression(ctx
, (call_expression_t
*)expr
, no_ret
);
854 return compile_comma_expression(ctx
, (binary_expression_t
*)expr
);
856 return compile_conditional_expression(ctx
, (conditional_expression_t
*)expr
);
858 return compile_delete_expression(ctx
, (unary_expression_t
*)expr
);
860 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
862 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq
);
864 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq2
);
866 return compile_function_expression(ctx
, (function_expression_t
*)expr
);
868 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
870 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
872 return push_instr_bstr(ctx
, OP_ident
, ((identifier_expression_t
*)expr
)->identifier
);
874 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_in
);
875 case EXPR_INSTANCEOF
:
876 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_instanceof
);
878 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
880 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
882 return compile_literal(ctx
, ((literal_expression_t
*)expr
)->literal
);
884 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
886 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
888 return compile_member_expression(ctx
, (member_expression_t
*)expr
);
890 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_minus
);
892 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
894 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
896 return compile_new_expression(ctx
, (call_expression_t
*)expr
);
898 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq
);
900 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq2
);
902 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_nz
);
904 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_tonum
);
906 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, -1);
908 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, 1);
910 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, -1);
912 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, 1);
914 return compile_object_literal(ctx
, (property_value_expression_t
*)expr
);
916 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
918 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
920 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
922 return push_instr(ctx
, OP_this
) == -1 ? E_OUTOFMEMORY
: S_OK
;
924 return compile_typeof_expression(ctx
, (unary_expression_t
*)expr
);
926 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_void
);
928 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
936 static HRESULT
compile_expression(compiler_ctx_t
*ctx
, expression_t
*expr
)
938 return compile_expression_noret(ctx
, expr
, NULL
);
941 /* ECMA-262 3rd Edition 12.1 */
942 static HRESULT
compile_block_statement(compiler_ctx_t
*ctx
, statement_t
*iter
)
946 /* FIXME: do it only if needed */
948 return push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
;
951 hres
= compile_statement(ctx
, NULL
, iter
);
959 if(push_instr(ctx
, OP_pop
) == -1)
960 return E_OUTOFMEMORY
;
966 /* ECMA-262 3rd Edition 12.2 */
967 static HRESULT
compile_variable_list(compiler_ctx_t
*ctx
, variable_declaration_t
*list
)
969 variable_declaration_t
*iter
;
972 for(iter
= list
; iter
; iter
= iter
->next
) {
976 hres
= compile_expression(ctx
, iter
->expr
);
980 hres
= push_instr_bstr(ctx
, OP_var_set
, iter
->identifier
);
988 /* ECMA-262 3rd Edition 12.2 */
989 static HRESULT
compile_var_statement(compiler_ctx_t
*ctx
, var_statement_t
*stat
)
993 hres
= compile_variable_list(ctx
, stat
->variable_list
);
997 return push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
;
1000 /* ECMA-262 3rd Edition 12.4 */
1001 static HRESULT
compile_expression_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1003 BOOL no_ret
= FALSE
;
1006 hres
= compile_expression_noret(ctx
, stat
->expr
, &no_ret
);
1010 /* FIXME: that's a big potential optimization */
1011 if(no_ret
&& !push_instr(ctx
, OP_undefined
) == -1)
1012 return E_OUTOFMEMORY
;
1017 /* ECMA-262 3rd Edition 12.5 */
1018 static HRESULT
compile_if_statement(compiler_ctx_t
*ctx
, if_statement_t
*stat
)
1020 unsigned jmp_else
, jmp_end
;
1023 hres
= compile_expression(ctx
, stat
->expr
);
1027 jmp_else
= push_instr(ctx
, OP_jmp_z
);
1029 return E_OUTOFMEMORY
;
1031 hres
= compile_statement(ctx
, NULL
, stat
->if_stat
);
1035 jmp_end
= push_instr(ctx
, OP_jmp
);
1037 return E_OUTOFMEMORY
;
1039 instr_ptr(ctx
, jmp_else
)->arg1
.uint
= ctx
->code_off
;
1041 if(stat
->else_stat
) {
1042 hres
= compile_statement(ctx
, NULL
, stat
->else_stat
);
1046 /* FIXME: We could sometimes avoid it */
1047 if(push_instr(ctx
, OP_undefined
) == -1)
1048 return E_OUTOFMEMORY
;
1051 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->code_off
;
1055 /* ECMA-262 3rd Edition 12.6.2 */
1056 static HRESULT
compile_while_statement(compiler_ctx_t
*ctx
, while_statement_t
*stat
)
1058 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1062 stat_ctx
.break_label
= alloc_label(ctx
);
1063 if(stat_ctx
.break_label
== -1)
1064 return E_OUTOFMEMORY
;
1066 stat_ctx
.continue_label
= alloc_label(ctx
);
1067 if(stat_ctx
.continue_label
== -1)
1068 return E_OUTOFMEMORY
;
1070 if(!stat
->do_while
) {
1072 if(push_instr(ctx
, OP_undefined
) == -1)
1073 return E_OUTOFMEMORY
;
1075 jmp_off
= ctx
->code_off
;
1076 label_set_addr(ctx
, stat_ctx
.continue_label
);
1077 hres
= compile_expression(ctx
, stat
->expr
);
1081 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1085 if(push_instr(ctx
, OP_pop
) == -1)
1086 return E_OUTOFMEMORY
;
1088 jmp_off
= ctx
->code_off
;
1091 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1095 if(stat
->do_while
) {
1096 label_set_addr(ctx
, stat_ctx
.continue_label
);
1097 hres
= compile_expression(ctx
, stat
->expr
);
1101 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1105 if(push_instr(ctx
, OP_pop
) == -1)
1106 return E_OUTOFMEMORY
;
1109 hres
= push_instr_uint(ctx
, OP_jmp
, jmp_off
);
1113 label_set_addr(ctx
, stat_ctx
.break_label
);
1117 /* ECMA-262 3rd Edition 12.6.3 */
1118 static HRESULT
compile_for_statement(compiler_ctx_t
*ctx
, for_statement_t
*stat
)
1120 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1124 if(stat
->variable_list
) {
1125 hres
= compile_variable_list(ctx
, stat
->variable_list
);
1128 }else if(stat
->begin_expr
) {
1129 BOOL no_ret
= FALSE
;
1131 hres
= compile_expression_noret(ctx
, stat
->begin_expr
, &no_ret
);
1134 if(!no_ret
&& push_instr(ctx
, OP_pop
) == -1)
1135 return E_OUTOFMEMORY
;
1138 stat_ctx
.break_label
= alloc_label(ctx
);
1139 if(stat_ctx
.break_label
== -1)
1140 return E_OUTOFMEMORY
;
1142 stat_ctx
.continue_label
= alloc_label(ctx
);
1143 if(stat_ctx
.continue_label
== -1)
1144 return E_OUTOFMEMORY
;
1147 if(push_instr(ctx
, OP_undefined
) == -1)
1148 return E_OUTOFMEMORY
;
1150 expr_off
= ctx
->code_off
;
1153 hres
= compile_expression(ctx
, stat
->expr
);
1157 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1162 if(push_instr(ctx
, OP_pop
) == -1)
1163 return E_OUTOFMEMORY
;
1165 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1169 label_set_addr(ctx
, stat_ctx
.continue_label
);
1171 if(stat
->end_expr
) {
1172 BOOL no_ret
= FALSE
;
1174 hres
= compile_expression_noret(ctx
, stat
->end_expr
, &no_ret
);
1178 if(!no_ret
&& push_instr(ctx
, OP_pop
) == -1)
1179 return E_OUTOFMEMORY
;
1182 hres
= push_instr_uint(ctx
, OP_jmp
, expr_off
);
1186 label_set_addr(ctx
, stat_ctx
.break_label
);
1190 /* ECMA-262 3rd Edition 12.6.4 */
1191 static HRESULT
compile_forin_statement(compiler_ctx_t
*ctx
, forin_statement_t
*stat
)
1193 statement_ctx_t stat_ctx
= {4, FALSE
, FALSE
};
1196 if(stat
->variable
) {
1197 hres
= compile_variable_list(ctx
, stat
->variable
);
1202 stat_ctx
.break_label
= alloc_label(ctx
);
1203 if(stat_ctx
.break_label
== -1)
1204 return E_OUTOFMEMORY
;
1206 stat_ctx
.continue_label
= alloc_label(ctx
);
1207 if(stat_ctx
.continue_label
== -1)
1208 return E_OUTOFMEMORY
;
1210 hres
= compile_expression(ctx
, stat
->in_expr
);
1214 if(stat
->variable
) {
1215 hres
= push_instr_bstr_uint(ctx
, OP_identid
, stat
->variable
->identifier
, fdexNameEnsure
);
1218 }else if(is_memberid_expr(stat
->expr
->type
)) {
1219 hres
= compile_memberid_expression(ctx
, stat
->expr
, fdexNameEnsure
);
1223 hres
= push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
1227 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1231 hres
= push_instr_int(ctx
, OP_int
, DISPID_STARTENUM
);
1236 if(push_instr(ctx
, OP_undefined
) == -1)
1237 return E_OUTOFMEMORY
;
1239 label_set_addr(ctx
, stat_ctx
.continue_label
);
1240 hres
= push_instr_uint(ctx
, OP_forin
, stat_ctx
.break_label
);
1242 return E_OUTOFMEMORY
;
1244 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1248 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.continue_label
);
1252 label_set_addr(ctx
, stat_ctx
.break_label
);
1256 static HRESULT
pop_to_stat(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
)
1258 statement_ctx_t
*iter
= ctx
->stat_ctx
;
1259 unsigned stack_pop
= 0;
1262 if(iter
->using_scope
&& push_instr(ctx
, OP_pop_scope
) == -1)
1263 return E_OUTOFMEMORY
;
1264 if(iter
->using_except
&& push_instr(ctx
, OP_pop_except
) == -1)
1265 return E_OUTOFMEMORY
;
1266 stack_pop
+= iter
->stack_use
;
1267 if(iter
== stat_ctx
)
1272 /* FIXME: optimize */
1273 while(stack_pop
--) {
1274 if(push_instr(ctx
, OP_pop
) == -1)
1275 return E_OUTOFMEMORY
;
1281 /* ECMA-262 3rd Edition 12.7 */
1282 static HRESULT
compile_continue_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1284 statement_ctx_t
*pop_ctx
;
1287 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1288 if(pop_ctx
->continue_label
!= -1)
1293 WARN("continue outside loop\n");
1294 return JS_E_INVALID_CONTINUE
;
1297 if(stat
->identifier
)
1298 return push_instr(ctx
, OP_label
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1300 hres
= pop_to_stat(ctx
, pop_ctx
);
1304 if(push_instr(ctx
, OP_undefined
) == -1)
1305 return E_OUTOFMEMORY
;
1307 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->continue_label
);
1310 /* ECMA-262 3rd Edition 12.8 */
1311 static HRESULT
compile_break_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1313 statement_ctx_t
*pop_ctx
;
1316 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1317 if(pop_ctx
->break_label
!= -1)
1322 WARN("Break outside loop\n");
1323 return JS_E_INVALID_BREAK
;
1326 if(stat
->identifier
)
1327 return push_instr(ctx
, OP_label
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1329 hres
= pop_to_stat(ctx
, pop_ctx
);
1333 if(push_instr(ctx
, OP_undefined
) == -1)
1334 return E_OUTOFMEMORY
;
1336 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->break_label
);
1339 /* ECMA-262 3rd Edition 12.9 */
1340 static HRESULT
compile_return_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1344 hres
= pop_to_stat(ctx
, NULL
);
1349 hres
= compile_expression(ctx
, stat
->expr
);
1354 return push_instr(ctx
, OP_ret
) == -1 ? E_OUTOFMEMORY
: S_OK
;
1357 /* ECMA-262 3rd Edition 12.10 */
1358 static HRESULT
compile_with_statement(compiler_ctx_t
*ctx
, with_statement_t
*stat
)
1360 statement_ctx_t stat_ctx
= {0, TRUE
, FALSE
, -1, -1};
1363 hres
= compile_expression(ctx
, stat
->expr
);
1367 if(push_instr(ctx
, OP_push_scope
) == -1)
1368 return E_OUTOFMEMORY
;
1370 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1374 if(push_instr(ctx
, OP_pop_scope
) == -1)
1375 return E_OUTOFMEMORY
;
1380 /* ECMA-262 3rd Edition 12.13 */
1381 static HRESULT
compile_switch_statement(compiler_ctx_t
*ctx
, switch_statement_t
*stat
)
1383 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
, -1, -1};
1384 unsigned case_cnt
= 0, *case_jmps
, i
, default_jmp
;
1385 BOOL have_default
= FALSE
;
1386 statement_t
*stat_iter
;
1387 case_clausule_t
*iter
;
1390 hres
= compile_expression(ctx
, stat
->expr
);
1394 stat_ctx
.break_label
= alloc_label(ctx
);
1395 if(stat_ctx
.break_label
== -1)
1396 return E_OUTOFMEMORY
;
1398 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1403 case_jmps
= heap_alloc(case_cnt
* sizeof(*case_jmps
));
1405 return E_OUTOFMEMORY
;
1408 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1410 have_default
= TRUE
;
1414 hres
= compile_expression(ctx
, iter
->expr
);
1418 case_jmps
[i
] = push_instr(ctx
, OP_case
);
1419 if(case_jmps
[i
] == -1) {
1420 hres
= E_OUTOFMEMORY
;
1426 if(SUCCEEDED(hres
)) {
1427 if(push_instr(ctx
, OP_pop
) != -1) {
1428 default_jmp
= push_instr(ctx
, OP_jmp
);
1429 if(default_jmp
== -1)
1430 hres
= E_OUTOFMEMORY
;
1432 hres
= E_OUTOFMEMORY
;
1437 heap_free(case_jmps
);
1442 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1443 while(iter
->next
&& iter
->next
->stat
== iter
->stat
) {
1444 instr_ptr(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
)->arg1
.uint
= ctx
->code_off
;
1448 instr_ptr(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
)->arg1
.uint
= ctx
->code_off
;
1450 for(stat_iter
= iter
->stat
; stat_iter
&& (!iter
->next
|| iter
->next
->stat
!= stat_iter
); stat_iter
= stat_iter
->next
) {
1451 hres
= compile_statement(ctx
, &stat_ctx
, stat_iter
);
1455 if(stat_iter
->next
&& push_instr(ctx
, OP_pop
) == -1) {
1456 hres
= E_OUTOFMEMORY
;
1464 heap_free(case_jmps
);
1467 assert(i
== case_cnt
);
1470 instr_ptr(ctx
, default_jmp
)->arg1
.uint
= ctx
->code_off
;
1472 label_set_addr(ctx
, stat_ctx
.break_label
);
1476 /* ECMA-262 3rd Edition 12.13 */
1477 static HRESULT
compile_throw_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1481 hres
= compile_expression(ctx
, stat
->expr
);
1485 return push_instr(ctx
, OP_throw
) == -1 ? E_OUTOFMEMORY
: S_OK
;
1488 /* ECMA-262 3rd Edition 12.14 */
1489 static HRESULT
compile_try_statement(compiler_ctx_t
*ctx
, try_statement_t
*stat
)
1491 statement_ctx_t try_ctx
= {0, FALSE
, TRUE
, -1, -1}, catch_ctx
= {0, TRUE
, FALSE
, -1, -1};
1492 statement_ctx_t finally_ctx
= {2, FALSE
, FALSE
, -1, -1};
1493 unsigned push_except
;
1497 push_except
= push_instr(ctx
, OP_push_except
);
1498 if(push_except
== -1)
1499 return E_OUTOFMEMORY
;
1501 if(stat
->catch_block
) {
1502 ident
= compiler_alloc_bstr(ctx
, stat
->catch_block
->identifier
);
1504 return E_OUTOFMEMORY
;
1509 instr_ptr(ctx
, push_except
)->arg2
.bstr
= ident
;
1511 if(!stat
->catch_block
)
1512 try_ctx
.stack_use
= 2;
1514 hres
= compile_statement(ctx
, &try_ctx
, stat
->try_statement
);
1518 if(push_instr(ctx
, OP_pop_except
) == -1)
1519 return E_OUTOFMEMORY
;
1521 if(stat
->catch_block
) {
1522 unsigned jmp_finally
;
1524 jmp_finally
= push_instr(ctx
, OP_jmp
);
1525 if(jmp_finally
== -1)
1526 return E_OUTOFMEMORY
;
1528 instr_ptr(ctx
, push_except
)->arg1
.uint
= ctx
->code_off
;
1530 hres
= compile_statement(ctx
, &catch_ctx
, stat
->catch_block
->statement
);
1534 if(push_instr(ctx
, OP_pop_scope
) == -1)
1535 return E_OUTOFMEMORY
;
1537 instr_ptr(ctx
, jmp_finally
)->arg1
.uint
= ctx
->code_off
;
1539 instr_ptr(ctx
, push_except
)->arg1
.uint
= ctx
->code_off
;
1542 if(stat
->finally_statement
) {
1544 if(push_instr(ctx
, OP_pop
) == -1)
1545 return E_OUTOFMEMORY
;
1547 hres
= compile_statement(ctx
, stat
->catch_block
? NULL
: &finally_ctx
, stat
->finally_statement
);
1551 if(!stat
->catch_block
&& push_instr(ctx
, OP_end_finally
) == -1)
1552 return E_OUTOFMEMORY
;
1558 static HRESULT
compile_statement(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
1563 stat_ctx
->next
= ctx
->stat_ctx
;
1564 ctx
->stat_ctx
= stat_ctx
;
1567 switch(stat
->type
) {
1569 hres
= compile_block_statement(ctx
, ((block_statement_t
*)stat
)->stat_list
);
1572 hres
= compile_break_statement(ctx
, (branch_statement_t
*)stat
);
1575 hres
= compile_continue_statement(ctx
, (branch_statement_t
*)stat
);
1578 hres
= push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1581 hres
= compile_expression_statement(ctx
, (expression_statement_t
*)stat
);
1584 hres
= compile_for_statement(ctx
, (for_statement_t
*)stat
);
1587 hres
= compile_forin_statement(ctx
, (forin_statement_t
*)stat
);
1590 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
1593 hres
= push_instr(ctx
, OP_label
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1596 hres
= compile_return_statement(ctx
, (expression_statement_t
*)stat
);
1599 hres
= compile_switch_statement(ctx
, (switch_statement_t
*)stat
);
1602 hres
= compile_throw_statement(ctx
, (expression_statement_t
*)stat
);
1605 hres
= compile_try_statement(ctx
, (try_statement_t
*)stat
);
1608 hres
= compile_var_statement(ctx
, (var_statement_t
*)stat
);
1611 hres
= compile_while_statement(ctx
, (while_statement_t
*)stat
);
1614 hres
= compile_with_statement(ctx
, (with_statement_t
*)stat
);
1617 hres
= compile_interp_fallback(ctx
, stat
);
1621 assert(ctx
->stat_ctx
== stat_ctx
);
1622 ctx
->stat_ctx
= stat_ctx
->next
;
1628 static void resolve_labels(compiler_ctx_t
*ctx
, unsigned off
)
1632 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
1633 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->arg1
.uint
& LABEL_FLAG
)) {
1634 assert((instr
->arg1
.uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
1635 instr
->arg1
.uint
= ctx
->labels
[instr
->arg1
.uint
& ~LABEL_FLAG
];
1637 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
1640 ctx
->labels_cnt
= 0;
1643 void release_bytecode(bytecode_t
*code
)
1647 for(i
=0; i
< code
->bstr_cnt
; i
++)
1648 SysFreeString(code
->bstr_pool
[i
]);
1650 jsheap_free(&code
->heap
);
1651 heap_free(code
->bstr_pool
);
1652 heap_free(code
->instrs
);
1656 void release_compiler(compiler_ctx_t
*ctx
)
1661 static HRESULT
init_compiler(parser_ctx_t
*parser
)
1664 parser
->code
= heap_alloc_zero(sizeof(bytecode_t
));
1666 return E_OUTOFMEMORY
;
1667 jsheap_init(&parser
->code
->heap
);
1670 if(!parser
->compiler
) {
1671 parser
->compiler
= heap_alloc_zero(sizeof(compiler_ctx_t
));
1672 if(!parser
->compiler
)
1673 return E_OUTOFMEMORY
;
1675 parser
->compiler
->parser
= parser
;
1676 parser
->compiler
->code
= parser
->code
;
1682 HRESULT
compile_subscript_stat(parser_ctx_t
*parser
, statement_t
*stat
, BOOL from_eval
, unsigned *ret_off
)
1689 hres
= init_compiler(parser
);
1693 off
= parser
->compiler
->code_off
;
1695 hres
= compile_block_statement(parser
->compiler
, stat
);
1697 hres
= compile_statement(parser
->compiler
, NULL
, stat
);
1701 resolve_labels(parser
->compiler
, off
);
1703 if(!from_eval
&& push_instr(parser
->compiler
, OP_pop
) == -1)
1704 return E_OUTOFMEMORY
;
1705 if(push_instr(parser
->compiler
, OP_ret
) == -1)
1706 return E_OUTOFMEMORY
;
1708 if(TRACE_ON(jscript_disas
))
1709 dump_code(parser
->compiler
, off
);