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
);
29 typedef struct _statement_ctx_t
{
35 unsigned continue_label
;
37 struct _statement_ctx_t
*next
;
40 struct _compiler_ctx_t
{
51 statement_ctx_t
*stat_ctx
;
56 instr_arg_type_t arg1_type
;
57 instr_arg_type_t arg2_type
;
59 #define X(n,a,b,c) {#n,b,c},
64 static HRESULT
compile_expression(compiler_ctx_t
*,expression_t
*);
65 static HRESULT
compile_statement(compiler_ctx_t
*,statement_ctx_t
*,statement_t
*);
67 static inline void *compiler_alloc(bytecode_t
*code
, size_t size
)
69 return jsheap_alloc(&code
->heap
, size
);
72 static WCHAR
*compiler_alloc_string(bytecode_t
*code
, const WCHAR
*str
)
77 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
78 ret
= compiler_alloc(code
, size
);
80 memcpy(ret
, str
, size
);
84 static BSTR
compiler_alloc_bstr(compiler_ctx_t
*ctx
, const WCHAR
*str
)
86 if(!ctx
->code
->bstr_pool_size
) {
87 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
88 if(!ctx
->code
->bstr_pool
)
90 ctx
->code
->bstr_pool_size
= 8;
91 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
94 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
98 ctx
->code
->bstr_pool
= new_pool
;
99 ctx
->code
->bstr_pool_size
*= 2;
102 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
103 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
106 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
109 static unsigned push_instr(compiler_ctx_t
*ctx
, jsop_t op
)
111 assert(ctx
->code_size
>= ctx
->code_off
);
113 if(!ctx
->code_size
) {
114 ctx
->code
->instrs
= heap_alloc(64 * sizeof(instr_t
));
115 if(!ctx
->code
->instrs
)
118 }else if(ctx
->code_size
== ctx
->code_off
) {
121 new_instrs
= heap_realloc(ctx
->code
->instrs
, ctx
->code_size
*2*sizeof(instr_t
));
125 ctx
->code
->instrs
= new_instrs
;
129 ctx
->code
->instrs
[ctx
->code_off
].op
= op
;
130 return ctx
->code_off
++;
133 static inline instr_t
*instr_ptr(compiler_ctx_t
*ctx
, unsigned off
)
135 assert(off
< ctx
->code_off
);
136 return ctx
->code
->instrs
+ off
;
139 static HRESULT
push_instr_int(compiler_ctx_t
*ctx
, jsop_t op
, LONG arg
)
143 instr
= push_instr(ctx
, op
);
145 return E_OUTOFMEMORY
;
147 instr_ptr(ctx
, instr
)->arg1
.lng
= arg
;
151 static HRESULT
push_instr_str(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
156 str
= compiler_alloc_string(ctx
->code
, arg
);
158 return E_OUTOFMEMORY
;
160 instr
= push_instr(ctx
, op
);
162 return E_OUTOFMEMORY
;
164 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
168 static HRESULT
push_instr_bstr(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
173 str
= compiler_alloc_bstr(ctx
, arg
);
175 return E_OUTOFMEMORY
;
177 instr
= push_instr(ctx
, op
);
179 return E_OUTOFMEMORY
;
181 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
185 static HRESULT
push_instr_bstr_uint(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
190 str
= compiler_alloc_bstr(ctx
, arg1
);
192 return E_OUTOFMEMORY
;
194 instr
= push_instr(ctx
, op
);
196 return E_OUTOFMEMORY
;
198 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
199 instr_ptr(ctx
, instr
)->arg2
.uint
= arg2
;
203 static HRESULT
push_instr_uint_str(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
208 str
= compiler_alloc_string(ctx
->code
, arg2
);
210 return E_OUTOFMEMORY
;
212 instr
= push_instr(ctx
, op
);
214 return E_OUTOFMEMORY
;
216 instr_ptr(ctx
, instr
)->arg1
.uint
= arg1
;
217 instr_ptr(ctx
, instr
)->arg2
.str
= str
;
221 static HRESULT
push_instr_double(compiler_ctx_t
*ctx
, jsop_t op
, double arg
)
226 dbl
= compiler_alloc(ctx
->code
, sizeof(arg
));
228 return E_OUTOFMEMORY
;
231 instr
= push_instr(ctx
, op
);
233 return E_OUTOFMEMORY
;
235 instr_ptr(ctx
, instr
)->arg1
.dbl
= dbl
;
239 static HRESULT
push_instr_uint(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg
)
243 instr
= push_instr(ctx
, op
);
245 return E_OUTOFMEMORY
;
247 instr_ptr(ctx
, instr
)->arg1
.uint
= arg
;
251 static HRESULT
compile_binary_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
255 hres
= compile_expression(ctx
, expr
->expression1
);
259 hres
= compile_expression(ctx
, expr
->expression2
);
263 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
266 static HRESULT
compile_unary_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
)
270 hres
= compile_expression(ctx
, expr
->expression
);
274 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
277 /* ECMA-262 3rd Edition 11.2.1 */
278 static HRESULT
compile_member_expression(compiler_ctx_t
*ctx
, member_expression_t
*expr
)
282 hres
= compile_expression(ctx
, expr
->expression
);
286 return push_instr_bstr(ctx
, OP_member
, expr
->identifier
);
289 #define LABEL_FLAG 0x80000000
291 static unsigned alloc_label(compiler_ctx_t
*ctx
)
293 if(!ctx
->labels_size
) {
294 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
297 ctx
->labels_size
= 8;
298 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
299 unsigned *new_labels
;
301 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
305 ctx
->labels
= new_labels
;
306 ctx
->labels_size
*= 2;
309 return ctx
->labels_cnt
++ | LABEL_FLAG
;
312 static void label_set_addr(compiler_ctx_t
*ctx
, unsigned label
)
314 assert(label
& LABEL_FLAG
);
315 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->code_off
;
318 static inline BOOL
is_memberid_expr(expression_type_t type
)
320 return type
== EXPR_IDENT
|| type
== EXPR_MEMBER
|| type
== EXPR_ARRAY
;
323 static HRESULT
compile_memberid_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, unsigned flags
)
329 identifier_expression_t
*ident_expr
= (identifier_expression_t
*)expr
;
331 hres
= push_instr_bstr_uint(ctx
, OP_identid
, ident_expr
->identifier
, flags
);
335 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
;
337 hres
= compile_expression(ctx
, array_expr
->expression1
);
341 hres
= compile_expression(ctx
, array_expr
->expression2
);
345 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
349 member_expression_t
*member_expr
= (member_expression_t
*)expr
;
351 hres
= compile_expression(ctx
, member_expr
->expression
);
355 /* FIXME: Potential optimization */
356 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
360 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
370 static HRESULT
compile_increment_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
, int n
)
374 if(!is_memberid_expr(expr
->expression
->type
)) {
375 hres
= compile_expression(ctx
, expr
->expression
);
379 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
382 hres
= compile_memberid_expression(ctx
, expr
->expression
, fdexNameEnsure
);
386 return push_instr_int(ctx
, op
, n
);
389 /* ECMA-262 3rd Edition 11.14 */
390 static HRESULT
compile_comma_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
)
394 hres
= compile_expression(ctx
, expr
->expression1
);
398 if(push_instr(ctx
, OP_pop
) == -1)
399 return E_OUTOFMEMORY
;
401 return compile_expression(ctx
, expr
->expression2
);
404 /* ECMA-262 3rd Edition 11.11 */
405 static HRESULT
compile_logical_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
410 hres
= compile_expression(ctx
, expr
->expression1
);
414 instr
= push_instr(ctx
, op
);
416 return E_OUTOFMEMORY
;
418 hres
= compile_expression(ctx
, expr
->expression2
);
422 instr_ptr(ctx
, instr
)->arg1
.uint
= ctx
->code_off
;
426 /* ECMA-262 3rd Edition 11.12 */
427 static HRESULT
compile_conditional_expression(compiler_ctx_t
*ctx
, conditional_expression_t
*expr
)
429 unsigned jmp_false
, jmp_end
;
432 hres
= compile_expression(ctx
, expr
->expression
);
436 jmp_false
= push_instr(ctx
, OP_cnd_z
);
438 return E_OUTOFMEMORY
;
440 hres
= compile_expression(ctx
, expr
->true_expression
);
444 jmp_end
= push_instr(ctx
, OP_jmp
);
446 return E_OUTOFMEMORY
;
448 instr_ptr(ctx
, jmp_false
)->arg1
.uint
= ctx
->code_off
;
449 if(push_instr(ctx
, OP_pop
) == -1)
450 return E_OUTOFMEMORY
;
452 hres
= compile_expression(ctx
, expr
->false_expression
);
456 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->code_off
;
460 static HRESULT
compile_new_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
)
462 unsigned arg_cnt
= 0;
466 hres
= compile_expression(ctx
, expr
->expression
);
470 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
471 hres
= compile_expression(ctx
, arg
->expr
);
477 return push_instr_int(ctx
, OP_new
, arg_cnt
);
480 static HRESULT
compile_interp_fallback(compiler_ctx_t
*ctx
, statement_t
*stat
)
484 instr
= push_instr(ctx
, OP_tree
);
486 return E_OUTOFMEMORY
;
488 instr_ptr(ctx
, instr
)->arg1
.stat
= stat
;
492 static HRESULT
compile_call_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
, BOOL
*no_ret
)
494 unsigned arg_cnt
= 0;
500 if(is_memberid_expr(expr
->expression
->type
)) {
502 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
505 hres
= compile_expression(ctx
, expr
->expression
);
511 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
512 hres
= compile_expression(ctx
, arg
->expr
);
518 instr
= push_instr(ctx
, op
);
520 return E_OUTOFMEMORY
;
522 instr_ptr(ctx
, instr
)->arg1
.uint
= arg_cnt
;
523 instr_ptr(ctx
, instr
)->arg2
.lng
= no_ret
== NULL
;
529 static HRESULT
compile_delete_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
533 switch(expr
->expression
->type
) {
535 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
->expression
;
537 hres
= compile_expression(ctx
, array_expr
->expression1
);
541 hres
= compile_expression(ctx
, array_expr
->expression2
);
545 if(push_instr(ctx
, OP_delete
) == -1)
546 return E_OUTOFMEMORY
;
550 member_expression_t
*member_expr
= (member_expression_t
*)expr
->expression
;
552 hres
= compile_expression(ctx
, member_expr
->expression
);
556 /* FIXME: Potential optimization */
557 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
561 if(push_instr(ctx
, OP_delete
) == -1)
562 return E_OUTOFMEMORY
;
566 return push_instr_bstr(ctx
, OP_delete_ident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
568 const WCHAR fixmeW
[] = {'F','I','X','M','E',0};
570 WARN("invalid delete, unimplemented exception message\n");
572 hres
= compile_expression(ctx
, expr
->expression
);
576 return push_instr_uint_str(ctx
, OP_throw_type
, JS_E_INVALID_DELETE
, fixmeW
);
583 static HRESULT
compile_assign_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
587 if(!is_memberid_expr(expr
->expression1
->type
)) {
588 hres
= compile_expression(ctx
, expr
->expression1
);
592 hres
= compile_expression(ctx
, expr
->expression2
);
596 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
597 return E_OUTOFMEMORY
;
599 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
602 hres
= compile_memberid_expression(ctx
, expr
->expression1
, fdexNameEnsure
);
606 if(op
!= OP_LAST
&& push_instr(ctx
, OP_refval
) == -1)
607 return E_OUTOFMEMORY
;
609 hres
= compile_expression(ctx
, expr
->expression2
);
613 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
614 return E_OUTOFMEMORY
;
616 if(push_instr(ctx
, OP_assign
) == -1)
617 return E_OUTOFMEMORY
;
622 static HRESULT
compile_typeof_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
627 if(is_memberid_expr(expr
->expression
->type
)) {
628 if(expr
->expression
->type
== EXPR_IDENT
)
629 return push_instr_str(ctx
, OP_typeofident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
632 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
635 hres
= compile_expression(ctx
, expr
->expression
);
640 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
643 static HRESULT
compile_literal(compiler_ctx_t
*ctx
, literal_t
*literal
)
645 switch(literal
->type
) {
647 return push_instr_int(ctx
, OP_bool
, literal
->u
.bval
);
649 return push_instr_double(ctx
, OP_double
, literal
->u
.dval
);
651 return push_instr_int(ctx
, OP_int
, literal
->u
.lval
);
653 return push_instr(ctx
, OP_null
);
655 return push_instr_str(ctx
, OP_str
, literal
->u
.wstr
);
660 str
= compiler_alloc(ctx
->code
, (literal
->u
.regexp
.str_len
+1)*sizeof(WCHAR
));
662 return E_OUTOFMEMORY
;
663 memcpy(str
, literal
->u
.regexp
.str
, literal
->u
.regexp
.str_len
*sizeof(WCHAR
));
664 str
[literal
->u
.regexp
.str_len
] = 0;
666 instr
= push_instr(ctx
, OP_regexp
);
668 return E_OUTOFMEMORY
;
670 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
671 instr_ptr(ctx
, instr
)->arg2
.lng
= literal
->u
.regexp
.flags
;
679 static HRESULT
literal_as_bstr(compiler_ctx_t
*ctx
, literal_t
*literal
, BSTR
*str
)
681 switch(literal
->type
) {
683 *str
= compiler_alloc_bstr(ctx
, literal
->u
.wstr
);
686 *str
= int_to_bstr(literal
->u
.lval
);
689 return double_to_bstr(literal
->u
.dval
, str
);
694 return *str
? S_OK
: E_OUTOFMEMORY
;
697 static HRESULT
compile_array_literal(compiler_ctx_t
*ctx
, array_literal_expression_t
*expr
)
699 unsigned i
, elem_cnt
= expr
->length
;
700 array_element_t
*iter
;
703 for(iter
= expr
->element_list
; iter
; iter
= iter
->next
) {
704 elem_cnt
+= iter
->elision
+1;
706 for(i
=0; i
< iter
->elision
; i
++) {
707 if(push_instr(ctx
, OP_undefined
) == -1)
708 return E_OUTOFMEMORY
;
711 hres
= compile_expression(ctx
, iter
->expr
);
716 for(i
=0; i
< expr
->length
; i
++) {
717 if(push_instr(ctx
, OP_undefined
) == -1)
718 return E_OUTOFMEMORY
;
721 return push_instr_uint(ctx
, OP_carray
, elem_cnt
);
724 static HRESULT
compile_object_literal(compiler_ctx_t
*ctx
, property_value_expression_t
*expr
)
731 if(push_instr(ctx
, OP_new_obj
) == -1)
732 return E_OUTOFMEMORY
;
734 for(iter
= expr
->property_list
; iter
; iter
= iter
->next
) {
735 hres
= literal_as_bstr(ctx
, iter
->name
, &name
);
739 hres
= compile_expression(ctx
, iter
->value
);
743 instr
= push_instr(ctx
, OP_obj_prop
);
745 return E_OUTOFMEMORY
;
747 instr_ptr(ctx
, instr
)->arg1
.bstr
= name
;
753 static HRESULT
compile_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
)
757 /* FIXME: not exactly right */
759 return push_instr_bstr(ctx
, OP_ident
, expr
->identifier
);
761 instr
= push_instr(ctx
, OP_func
);
763 return E_OUTOFMEMORY
;
765 instr_ptr(ctx
, instr
)->arg1
.func
= expr
;
769 static HRESULT
compile_expression_noret(compiler_ctx_t
*ctx
, expression_t
*expr
, BOOL
*no_ret
)
773 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
775 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_z
);
777 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_array
);
779 return compile_array_literal(ctx
, (array_literal_expression_t
*)expr
);
781 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_LAST
);
783 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
785 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
787 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
789 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
791 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
793 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
795 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
796 case EXPR_ASSIGNLSHIFT
:
797 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
798 case EXPR_ASSIGNRSHIFT
:
799 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
800 case EXPR_ASSIGNRRSHIFT
:
801 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
803 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
805 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
807 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_bneg
);
809 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
811 return compile_call_expression(ctx
, (call_expression_t
*)expr
, no_ret
);
813 return compile_comma_expression(ctx
, (binary_expression_t
*)expr
);
815 return compile_conditional_expression(ctx
, (conditional_expression_t
*)expr
);
817 return compile_delete_expression(ctx
, (unary_expression_t
*)expr
);
819 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
821 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq
);
823 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq2
);
825 return compile_function_expression(ctx
, (function_expression_t
*)expr
);
827 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
829 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
831 return push_instr_bstr(ctx
, OP_ident
, ((identifier_expression_t
*)expr
)->identifier
);
833 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_in
);
834 case EXPR_INSTANCEOF
:
835 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_instanceof
);
837 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
839 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
841 return compile_literal(ctx
, ((literal_expression_t
*)expr
)->literal
);
843 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
845 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
847 return compile_member_expression(ctx
, (member_expression_t
*)expr
);
849 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_minus
);
851 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
853 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
855 return compile_new_expression(ctx
, (call_expression_t
*)expr
);
857 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq
);
859 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq2
);
861 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_nz
);
863 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_tonum
);
865 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, -1);
867 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, 1);
869 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, -1);
871 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, 1);
873 return compile_object_literal(ctx
, (property_value_expression_t
*)expr
);
875 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
877 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
879 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
881 return push_instr(ctx
, OP_this
) == -1 ? E_OUTOFMEMORY
: S_OK
;
883 return compile_typeof_expression(ctx
, (unary_expression_t
*)expr
);
885 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_void
);
887 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
895 static HRESULT
compile_expression(compiler_ctx_t
*ctx
, expression_t
*expr
)
897 return compile_expression_noret(ctx
, expr
, NULL
);
900 /* ECMA-262 3rd Edition 12.1 */
901 static HRESULT
compile_block_statement(compiler_ctx_t
*ctx
, statement_t
*iter
)
905 /* FIXME: do it only if needed */
907 return push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
;
910 hres
= compile_statement(ctx
, NULL
, iter
);
918 if(push_instr(ctx
, OP_pop
) == -1)
919 return E_OUTOFMEMORY
;
925 /* ECMA-262 3rd Edition 12.2 */
926 static HRESULT
compile_variable_list(compiler_ctx_t
*ctx
, variable_declaration_t
*list
)
928 variable_declaration_t
*iter
;
931 for(iter
= list
; iter
; iter
= iter
->next
) {
935 hres
= compile_expression(ctx
, iter
->expr
);
939 hres
= push_instr_bstr(ctx
, OP_var_set
, iter
->identifier
);
947 /* ECMA-262 3rd Edition 12.2 */
948 static HRESULT
compile_var_statement(compiler_ctx_t
*ctx
, var_statement_t
*stat
)
952 hres
= compile_variable_list(ctx
, stat
->variable_list
);
956 return push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
;
959 /* ECMA-262 3rd Edition 12.4 */
960 static HRESULT
compile_expression_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
965 hres
= compile_expression_noret(ctx
, stat
->expr
, &no_ret
);
969 /* FIXME: that's a big potential optimization */
970 if(no_ret
&& !push_instr(ctx
, OP_undefined
) == -1)
971 return E_OUTOFMEMORY
;
976 /* ECMA-262 3rd Edition 12.5 */
977 static HRESULT
compile_if_statement(compiler_ctx_t
*ctx
, if_statement_t
*stat
)
979 unsigned jmp_else
, jmp_end
;
982 hres
= compile_expression(ctx
, stat
->expr
);
986 jmp_else
= push_instr(ctx
, OP_jmp_z
);
988 return E_OUTOFMEMORY
;
990 hres
= compile_statement(ctx
, NULL
, stat
->if_stat
);
994 jmp_end
= push_instr(ctx
, OP_jmp
);
996 return E_OUTOFMEMORY
;
998 instr_ptr(ctx
, jmp_else
)->arg1
.uint
= ctx
->code_off
;
1000 if(stat
->else_stat
) {
1001 hres
= compile_statement(ctx
, NULL
, stat
->else_stat
);
1005 /* FIXME: We could sometimes avoid it */
1006 if(push_instr(ctx
, OP_undefined
) == -1)
1007 return E_OUTOFMEMORY
;
1010 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->code_off
;
1014 /* ECMA-262 3rd Edition 12.6.2 */
1015 static HRESULT
compile_while_statement(compiler_ctx_t
*ctx
, while_statement_t
*stat
)
1017 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1018 unsigned off_backup
, jmp_off
;
1021 off_backup
= ctx
->code_off
;
1023 stat_ctx
.break_label
= alloc_label(ctx
);
1024 if(stat_ctx
.break_label
== -1)
1025 return E_OUTOFMEMORY
;
1027 stat_ctx
.continue_label
= alloc_label(ctx
);
1028 if(stat_ctx
.continue_label
== -1)
1029 return E_OUTOFMEMORY
;
1031 if(!stat
->do_while
) {
1033 if(push_instr(ctx
, OP_undefined
) == -1)
1034 return E_OUTOFMEMORY
;
1036 jmp_off
= ctx
->code_off
;
1037 label_set_addr(ctx
, stat_ctx
.continue_label
);
1038 hres
= compile_expression(ctx
, stat
->expr
);
1042 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1046 if(push_instr(ctx
, OP_pop
) == -1)
1047 return E_OUTOFMEMORY
;
1049 jmp_off
= ctx
->code_off
;
1052 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1053 if(hres
== E_NOTIMPL
) {
1054 ctx
->code_off
= off_backup
;
1055 stat
->stat
.eval
= while_statement_eval
;
1056 return compile_interp_fallback(ctx
, &stat
->stat
);
1061 if(stat
->do_while
) {
1062 label_set_addr(ctx
, stat_ctx
.continue_label
);
1063 hres
= compile_expression(ctx
, stat
->expr
);
1067 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1071 if(push_instr(ctx
, OP_pop
) == -1)
1072 return E_OUTOFMEMORY
;
1075 hres
= push_instr_uint(ctx
, OP_jmp
, jmp_off
);
1079 label_set_addr(ctx
, stat_ctx
.break_label
);
1083 /* ECMA-262 3rd Edition 12.6.3 */
1084 static HRESULT
compile_for_statement(compiler_ctx_t
*ctx
, for_statement_t
*stat
)
1086 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1087 unsigned off_backup
, expr_off
;
1090 off_backup
= ctx
->code_off
;
1092 if(stat
->variable_list
) {
1093 hres
= compile_variable_list(ctx
, stat
->variable_list
);
1096 }else if(stat
->begin_expr
) {
1097 BOOL no_ret
= FALSE
;
1099 hres
= compile_expression_noret(ctx
, stat
->begin_expr
, &no_ret
);
1102 if(!no_ret
&& push_instr(ctx
, OP_pop
) == -1)
1103 return E_OUTOFMEMORY
;
1106 stat_ctx
.break_label
= alloc_label(ctx
);
1107 if(stat_ctx
.break_label
== -1)
1108 return E_OUTOFMEMORY
;
1110 stat_ctx
.continue_label
= alloc_label(ctx
);
1111 if(stat_ctx
.continue_label
== -1)
1112 return E_OUTOFMEMORY
;
1115 if(push_instr(ctx
, OP_undefined
) == -1)
1116 return E_OUTOFMEMORY
;
1118 expr_off
= ctx
->code_off
;
1121 hres
= compile_expression(ctx
, stat
->expr
);
1125 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1130 if(push_instr(ctx
, OP_pop
) == -1)
1131 return E_OUTOFMEMORY
;
1133 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1134 if(hres
== E_NOTIMPL
) {
1135 ctx
->code_off
= off_backup
;
1136 stat
->stat
.eval
= for_statement_eval
;
1137 return compile_interp_fallback(ctx
, &stat
->stat
);
1142 label_set_addr(ctx
, stat_ctx
.continue_label
);
1144 if(stat
->end_expr
) {
1145 BOOL no_ret
= FALSE
;
1147 hres
= compile_expression_noret(ctx
, stat
->end_expr
, &no_ret
);
1151 if(!no_ret
&& push_instr(ctx
, OP_pop
) == -1)
1152 return E_OUTOFMEMORY
;
1155 hres
= push_instr_uint(ctx
, OP_jmp
, expr_off
);
1159 label_set_addr(ctx
, stat_ctx
.break_label
);
1163 /* ECMA-262 3rd Edition 12.6.4 */
1164 static HRESULT
compile_forin_statement(compiler_ctx_t
*ctx
, forin_statement_t
*stat
)
1166 statement_ctx_t stat_ctx
= {4, FALSE
, FALSE
};
1167 unsigned off_backup
= ctx
->code_off
;
1170 if(stat
->variable
) {
1171 hres
= compile_variable_list(ctx
, stat
->variable
);
1176 stat_ctx
.break_label
= alloc_label(ctx
);
1177 if(stat_ctx
.break_label
== -1)
1178 return E_OUTOFMEMORY
;
1180 stat_ctx
.continue_label
= alloc_label(ctx
);
1181 if(stat_ctx
.continue_label
== -1)
1182 return E_OUTOFMEMORY
;
1184 hres
= compile_expression(ctx
, stat
->in_expr
);
1188 if(stat
->variable
) {
1189 hres
= push_instr_bstr_uint(ctx
, OP_identid
, stat
->variable
->identifier
, fdexNameEnsure
);
1192 }else if(is_memberid_expr(stat
->expr
->type
)) {
1193 hres
= compile_memberid_expression(ctx
, stat
->expr
, fdexNameEnsure
);
1197 hres
= push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
1201 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1205 hres
= push_instr_int(ctx
, OP_int
, DISPID_STARTENUM
);
1210 if(push_instr(ctx
, OP_undefined
) == -1)
1211 return E_OUTOFMEMORY
;
1213 label_set_addr(ctx
, stat_ctx
.continue_label
);
1214 hres
= push_instr_uint(ctx
, OP_forin
, stat_ctx
.break_label
);
1216 return E_OUTOFMEMORY
;
1218 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1219 if(hres
== E_NOTIMPL
) {
1220 ctx
->code_off
= off_backup
;
1221 stat
->stat
.eval
= forin_statement_eval
;
1222 return compile_interp_fallback(ctx
, &stat
->stat
);
1227 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.continue_label
);
1231 label_set_addr(ctx
, stat_ctx
.break_label
);
1235 static HRESULT
pop_to_stat(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
)
1237 statement_ctx_t
*iter
= ctx
->stat_ctx
;
1238 unsigned stack_pop
= 0;
1241 if(iter
->using_scope
&& push_instr(ctx
, OP_pop_scope
) == -1)
1242 return E_OUTOFMEMORY
;
1243 if(iter
->using_except
&& push_instr(ctx
, OP_pop_except
) == -1)
1244 return E_OUTOFMEMORY
;
1245 stack_pop
+= iter
->stack_use
;
1246 if(iter
== stat_ctx
)
1251 /* FIXME: optimize */
1252 while(stack_pop
--) {
1253 if(push_instr(ctx
, OP_pop
) == -1)
1254 return E_OUTOFMEMORY
;
1260 /* ECMA-262 3rd Edition 12.7 */
1261 static HRESULT
compile_continue_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1263 statement_ctx_t
*pop_ctx
;
1266 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1267 if(pop_ctx
->continue_label
!= -1)
1271 if(!pop_ctx
|| stat
->identifier
) {
1272 stat
->stat
.eval
= continue_statement_eval
;
1273 return compile_interp_fallback(ctx
, &stat
->stat
);
1276 hres
= pop_to_stat(ctx
, pop_ctx
);
1280 if(push_instr(ctx
, OP_undefined
) == -1)
1281 return E_OUTOFMEMORY
;
1283 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->continue_label
);
1286 /* ECMA-262 3rd Edition 12.8 */
1287 static HRESULT
compile_break_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1289 statement_ctx_t
*pop_ctx
;
1292 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1293 if(pop_ctx
->break_label
!= -1)
1297 if(!pop_ctx
|| stat
->identifier
) {
1298 stat
->stat
.eval
= break_statement_eval
;
1299 return compile_interp_fallback(ctx
, &stat
->stat
);
1302 hres
= pop_to_stat(ctx
, pop_ctx
);
1306 if(push_instr(ctx
, OP_undefined
) == -1)
1307 return E_OUTOFMEMORY
;
1309 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->break_label
);
1312 /* ECMA-262 3rd Edition 12.10 */
1313 static HRESULT
compile_with_statement(compiler_ctx_t
*ctx
, with_statement_t
*stat
)
1315 statement_ctx_t stat_ctx
= {0, TRUE
, FALSE
, -1, -1};
1318 hres
= compile_expression(ctx
, stat
->expr
);
1322 if(push_instr(ctx
, OP_push_scope
) == -1)
1323 return E_OUTOFMEMORY
;
1325 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1329 if(push_instr(ctx
, OP_pop_scope
) == -1)
1330 return E_OUTOFMEMORY
;
1335 /* ECMA-262 3rd Edition 12.13 */
1336 static HRESULT
compile_switch_statement(compiler_ctx_t
*ctx
, switch_statement_t
*stat
)
1338 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
, -1, -1};
1339 unsigned case_cnt
= 0, *case_jmps
, i
, default_jmp
;
1340 BOOL have_default
= FALSE
;
1341 statement_t
*stat_iter
;
1342 case_clausule_t
*iter
;
1343 unsigned off_backup
;
1346 off_backup
= ctx
->code_off
;
1348 hres
= compile_expression(ctx
, stat
->expr
);
1352 stat_ctx
.break_label
= alloc_label(ctx
);
1353 if(stat_ctx
.break_label
== -1)
1354 return E_OUTOFMEMORY
;
1356 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1361 case_jmps
= heap_alloc(case_cnt
* sizeof(*case_jmps
));
1363 return E_OUTOFMEMORY
;
1366 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1368 have_default
= TRUE
;
1372 hres
= compile_expression(ctx
, iter
->expr
);
1376 case_jmps
[i
] = push_instr(ctx
, OP_case
);
1377 if(case_jmps
[i
] == -1) {
1378 hres
= E_OUTOFMEMORY
;
1384 if(SUCCEEDED(hres
)) {
1385 if(push_instr(ctx
, OP_pop
) != -1) {
1386 default_jmp
= push_instr(ctx
, OP_jmp
);
1387 if(default_jmp
== -1)
1388 hres
= E_OUTOFMEMORY
;
1390 hres
= E_OUTOFMEMORY
;
1395 heap_free(case_jmps
);
1400 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1401 while(iter
->next
&& iter
->next
->stat
== iter
->stat
) {
1402 instr_ptr(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
)->arg1
.uint
= ctx
->code_off
;
1406 instr_ptr(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
)->arg1
.uint
= ctx
->code_off
;
1408 for(stat_iter
= iter
->stat
; stat_iter
&& (!iter
->next
|| iter
->next
->stat
!= stat_iter
); stat_iter
= stat_iter
->next
) {
1409 hres
= compile_statement(ctx
, &stat_ctx
, stat_iter
);
1410 if(hres
== E_NOTIMPL
) {
1411 ctx
->code_off
= off_backup
;
1412 stat
->stat
.eval
= switch_statement_eval
;
1413 return compile_interp_fallback(ctx
, &stat
->stat
);
1418 if(stat_iter
->next
&& push_instr(ctx
, OP_pop
) == -1) {
1419 hres
= E_OUTOFMEMORY
;
1427 heap_free(case_jmps
);
1430 assert(i
== case_cnt
);
1433 instr_ptr(ctx
, default_jmp
)->arg1
.uint
= ctx
->code_off
;
1435 label_set_addr(ctx
, stat_ctx
.break_label
);
1439 /* ECMA-262 3rd Edition 12.13 */
1440 static HRESULT
compile_throw_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1444 hres
= compile_expression(ctx
, stat
->expr
);
1448 return push_instr(ctx
, OP_throw
) == -1 ? E_OUTOFMEMORY
: S_OK
;
1451 /* ECMA-262 3rd Edition 12.14 */
1452 static HRESULT
compile_try_statement(compiler_ctx_t
*ctx
, try_statement_t
*stat
)
1454 statement_ctx_t try_ctx
= {0, FALSE
, TRUE
, -1, -1}, catch_ctx
= {0, TRUE
, FALSE
, -1, -1};
1455 statement_ctx_t finally_ctx
= {2, FALSE
, FALSE
, -1, -1};
1456 unsigned off_backup
, push_except
;
1460 off_backup
= ctx
->code_off
;
1462 push_except
= push_instr(ctx
, OP_push_except
);
1463 if(push_except
== -1)
1464 return E_OUTOFMEMORY
;
1466 if(stat
->catch_block
) {
1467 ident
= compiler_alloc_bstr(ctx
, stat
->catch_block
->identifier
);
1469 return E_OUTOFMEMORY
;
1474 instr_ptr(ctx
, push_except
)->arg2
.bstr
= ident
;
1476 if(!stat
->catch_block
)
1477 try_ctx
.stack_use
= 2;
1479 hres
= compile_statement(ctx
, &try_ctx
, stat
->try_statement
);
1480 if(hres
== E_NOTIMPL
) {
1481 ctx
->code_off
= off_backup
;
1482 stat
->stat
.eval
= try_statement_eval
;
1483 return compile_interp_fallback(ctx
, &stat
->stat
);
1488 if(push_instr(ctx
, OP_pop_except
) == -1)
1489 return E_OUTOFMEMORY
;
1491 if(stat
->catch_block
) {
1492 unsigned jmp_finally
;
1494 jmp_finally
= push_instr(ctx
, OP_jmp
);
1495 if(jmp_finally
== -1)
1496 return E_OUTOFMEMORY
;
1498 instr_ptr(ctx
, push_except
)->arg1
.uint
= ctx
->code_off
;
1500 hres
= compile_statement(ctx
, &catch_ctx
, stat
->catch_block
->statement
);
1501 if(hres
== E_NOTIMPL
) {
1502 ctx
->code_off
= off_backup
;
1503 stat
->stat
.eval
= try_statement_eval
;
1504 return compile_interp_fallback(ctx
, &stat
->stat
);
1509 if(push_instr(ctx
, OP_pop_scope
) == -1)
1510 return E_OUTOFMEMORY
;
1512 instr_ptr(ctx
, jmp_finally
)->arg1
.uint
= ctx
->code_off
;
1514 instr_ptr(ctx
, push_except
)->arg1
.uint
= ctx
->code_off
;
1517 if(stat
->finally_statement
) {
1519 if(push_instr(ctx
, OP_pop
) == -1)
1520 return E_OUTOFMEMORY
;
1522 hres
= compile_statement(ctx
, stat
->catch_block
? NULL
: &finally_ctx
, stat
->finally_statement
);
1523 if(hres
== E_NOTIMPL
) {
1524 ctx
->code_off
= off_backup
;
1525 stat
->stat
.eval
= try_statement_eval
;
1526 return compile_interp_fallback(ctx
, &stat
->stat
);
1531 if(!stat
->catch_block
&& push_instr(ctx
, OP_end_finally
) == -1)
1532 return E_OUTOFMEMORY
;
1538 static HRESULT
compile_statement(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
1543 stat_ctx
->next
= ctx
->stat_ctx
;
1544 ctx
->stat_ctx
= stat_ctx
;
1547 switch(stat
->type
) {
1549 hres
= compile_block_statement(ctx
, ((block_statement_t
*)stat
)->stat_list
);
1552 hres
= compile_break_statement(ctx
, (branch_statement_t
*)stat
);
1555 hres
= compile_continue_statement(ctx
, (branch_statement_t
*)stat
);
1558 hres
= push_instr(ctx
, OP_undefined
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1561 hres
= compile_expression_statement(ctx
, (expression_statement_t
*)stat
);
1564 hres
= compile_for_statement(ctx
, (for_statement_t
*)stat
);
1567 hres
= compile_forin_statement(ctx
, (forin_statement_t
*)stat
);
1570 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
1573 hres
= push_instr(ctx
, OP_label
) == -1 ? E_OUTOFMEMORY
: S_OK
; /* FIXME */
1576 hres
= compile_switch_statement(ctx
, (switch_statement_t
*)stat
);
1579 hres
= compile_throw_statement(ctx
, (expression_statement_t
*)stat
);
1582 hres
= compile_try_statement(ctx
, (try_statement_t
*)stat
);
1585 hres
= compile_var_statement(ctx
, (var_statement_t
*)stat
);
1588 hres
= compile_while_statement(ctx
, (while_statement_t
*)stat
);
1591 hres
= compile_with_statement(ctx
, (with_statement_t
*)stat
);
1594 hres
= compile_interp_fallback(ctx
, stat
);
1598 assert(ctx
->stat_ctx
== stat_ctx
);
1599 ctx
->stat_ctx
= stat_ctx
->next
;
1605 static void resolve_labels(compiler_ctx_t
*ctx
, unsigned off
)
1609 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
1610 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->arg1
.uint
& LABEL_FLAG
)) {
1611 assert((instr
->arg1
.uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
1612 instr
->arg1
.uint
= ctx
->labels
[instr
->arg1
.uint
& ~LABEL_FLAG
];
1614 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
1617 ctx
->labels_cnt
= 0;
1620 void release_bytecode(bytecode_t
*code
)
1624 for(i
=0; i
< code
->bstr_cnt
; i
++)
1625 SysFreeString(code
->bstr_pool
[i
]);
1627 jsheap_free(&code
->heap
);
1628 heap_free(code
->bstr_pool
);
1629 heap_free(code
->instrs
);
1633 void release_compiler(compiler_ctx_t
*ctx
)
1638 static HRESULT
init_compiler(parser_ctx_t
*parser
)
1641 parser
->code
= heap_alloc_zero(sizeof(bytecode_t
));
1643 return E_OUTOFMEMORY
;
1644 jsheap_init(&parser
->code
->heap
);
1647 if(!parser
->compiler
) {
1648 parser
->compiler
= heap_alloc_zero(sizeof(compiler_ctx_t
));
1649 if(!parser
->compiler
)
1650 return E_OUTOFMEMORY
;
1652 parser
->compiler
->parser
= parser
;
1653 parser
->compiler
->code
= parser
->code
;
1659 HRESULT
compile_subscript(parser_ctx_t
*parser
, expression_t
*expr
, unsigned *ret_off
)
1663 hres
= init_compiler(parser
);
1667 *ret_off
= parser
->compiler
->code_off
;
1668 hres
= compile_expression(parser
->compiler
, expr
);
1672 return push_instr(parser
->compiler
, OP_ret
) == -1 ? E_OUTOFMEMORY
: S_OK
;
1675 HRESULT
compile_subscript_stat(parser_ctx_t
*parser
, statement_t
*stat
, BOOL compile_block
, unsigned *ret_off
)
1681 hres
= init_compiler(parser
);
1685 *ret_off
= parser
->compiler
->code_off
;
1686 if(compile_block
&& stat
->next
)
1687 hres
= compile_block_statement(parser
->compiler
, stat
);
1689 hres
= compile_statement(parser
->compiler
, NULL
, stat
);
1693 resolve_labels(parser
->compiler
, *ret_off
);
1695 return push_instr(parser
->compiler
, OP_ret
) == -1 ? E_OUTOFMEMORY
: S_OK
;