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 struct _compiler_ctx_t
{
37 static HRESULT
compile_expression(compiler_ctx_t
*,expression_t
*);
39 static inline void *compiler_alloc(bytecode_t
*code
, size_t size
)
41 return jsheap_alloc(&code
->heap
, size
);
44 static WCHAR
*compiler_alloc_string(bytecode_t
*code
, const WCHAR
*str
)
49 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
50 ret
= compiler_alloc(code
, size
);
52 memcpy(ret
, str
, size
);
56 static BSTR
compiler_alloc_bstr(compiler_ctx_t
*ctx
, const WCHAR
*str
)
58 if(!ctx
->code
->bstr_pool_size
) {
59 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
60 if(!ctx
->code
->bstr_pool
)
62 ctx
->code
->bstr_pool_size
= 8;
63 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
66 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
70 ctx
->code
->bstr_pool
= new_pool
;
71 ctx
->code
->bstr_pool_size
*= 2;
74 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
75 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
78 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
81 static unsigned push_instr(compiler_ctx_t
*ctx
, jsop_t op
)
83 assert(ctx
->code_size
>= ctx
->code_off
);
86 ctx
->code
->instrs
= heap_alloc(64 * sizeof(instr_t
));
87 if(!ctx
->code
->instrs
)
90 }else if(ctx
->code_size
== ctx
->code_off
) {
93 new_instrs
= heap_realloc(ctx
->code
->instrs
, ctx
->code_size
*2*sizeof(instr_t
));
97 ctx
->code
->instrs
= new_instrs
;
101 ctx
->code
->instrs
[ctx
->code_off
].op
= op
;
102 return ctx
->code_off
++;
105 static inline instr_t
*instr_ptr(compiler_ctx_t
*ctx
, unsigned off
)
107 assert(off
< ctx
->code_off
);
108 return ctx
->code
->instrs
+ off
;
111 static HRESULT
push_instr_int(compiler_ctx_t
*ctx
, jsop_t op
, LONG arg
)
115 instr
= push_instr(ctx
, op
);
117 return E_OUTOFMEMORY
;
119 instr_ptr(ctx
, instr
)->arg1
.lng
= arg
;
123 static HRESULT
push_instr_str(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
128 str
= compiler_alloc_string(ctx
->code
, arg
);
130 return E_OUTOFMEMORY
;
132 instr
= push_instr(ctx
, op
);
134 return E_OUTOFMEMORY
;
136 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
140 static HRESULT
push_instr_bstr(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
145 str
= compiler_alloc_bstr(ctx
, arg
);
147 return E_OUTOFMEMORY
;
149 instr
= push_instr(ctx
, op
);
151 return E_OUTOFMEMORY
;
153 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
157 static HRESULT
push_instr_bstr_uint(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
162 str
= compiler_alloc_bstr(ctx
, arg1
);
164 return E_OUTOFMEMORY
;
166 instr
= push_instr(ctx
, op
);
168 return E_OUTOFMEMORY
;
170 instr_ptr(ctx
, instr
)->arg1
.bstr
= str
;
171 instr_ptr(ctx
, instr
)->arg2
.uint
= arg2
;
175 static HRESULT
push_instr_uint_str(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
180 str
= compiler_alloc_string(ctx
->code
, arg2
);
182 return E_OUTOFMEMORY
;
184 instr
= push_instr(ctx
, op
);
186 return E_OUTOFMEMORY
;
188 instr_ptr(ctx
, instr
)->arg1
.uint
= arg1
;
189 instr_ptr(ctx
, instr
)->arg2
.str
= str
;
193 static HRESULT
push_instr_double(compiler_ctx_t
*ctx
, jsop_t op
, double arg
)
198 dbl
= compiler_alloc(ctx
->code
, sizeof(arg
));
200 return E_OUTOFMEMORY
;
203 instr
= push_instr(ctx
, op
);
205 return E_OUTOFMEMORY
;
207 instr_ptr(ctx
, instr
)->arg1
.dbl
= dbl
;
211 static HRESULT
push_instr_uint(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg
)
215 instr
= push_instr(ctx
, op
);
217 return E_OUTOFMEMORY
;
219 instr_ptr(ctx
, instr
)->arg1
.uint
= arg
;
223 static HRESULT
compile_binary_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
227 hres
= compile_expression(ctx
, expr
->expression1
);
231 hres
= compile_expression(ctx
, expr
->expression2
);
235 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
238 static HRESULT
compile_unary_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
)
242 hres
= compile_expression(ctx
, expr
->expression
);
246 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
249 /* ECMA-262 3rd Edition 11.2.1 */
250 static HRESULT
compile_member_expression(compiler_ctx_t
*ctx
, member_expression_t
*expr
)
254 hres
= compile_expression(ctx
, expr
->expression
);
258 return push_instr_bstr(ctx
, OP_member
, expr
->identifier
);
261 static inline BOOL
is_memberid_expr(expression_type_t type
)
263 return type
== EXPR_IDENT
|| type
== EXPR_MEMBER
|| type
== EXPR_ARRAY
;
266 static HRESULT
compile_memberid_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, unsigned flags
)
272 identifier_expression_t
*ident_expr
= (identifier_expression_t
*)expr
;
274 hres
= push_instr_bstr_uint(ctx
, OP_identid
, ident_expr
->identifier
, flags
);
278 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
;
280 hres
= compile_expression(ctx
, array_expr
->expression1
);
284 hres
= compile_expression(ctx
, array_expr
->expression2
);
288 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
292 member_expression_t
*member_expr
= (member_expression_t
*)expr
;
294 hres
= compile_expression(ctx
, member_expr
->expression
);
298 /* FIXME: Potential optimization */
299 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
303 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
313 static HRESULT
compile_increment_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
, int n
)
317 if(!is_memberid_expr(expr
->expression
->type
)) {
318 hres
= compile_expression(ctx
, expr
->expression
);
322 return push_instr_uint(ctx
, OP_throw
, JS_E_ILLEGAL_ASSIGN
);
325 hres
= compile_memberid_expression(ctx
, expr
->expression
, fdexNameEnsure
);
329 return push_instr_int(ctx
, op
, n
);
332 /* ECMA-262 3rd Edition 11.14 */
333 static HRESULT
compile_comma_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
)
337 hres
= compile_expression(ctx
, expr
->expression1
);
341 if(push_instr(ctx
, OP_pop
) == -1)
342 return E_OUTOFMEMORY
;
344 return compile_expression(ctx
, expr
->expression2
);
347 /* ECMA-262 3rd Edition 11.11 */
348 static HRESULT
compile_logical_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
353 hres
= compile_expression(ctx
, expr
->expression1
);
357 instr
= push_instr(ctx
, op
);
359 return E_OUTOFMEMORY
;
361 hres
= compile_expression(ctx
, expr
->expression2
);
365 instr_ptr(ctx
, instr
)->arg1
.uint
= ctx
->code_off
;
369 /* ECMA-262 3rd Edition 11.12 */
370 static HRESULT
compile_conditional_expression(compiler_ctx_t
*ctx
, conditional_expression_t
*expr
)
372 unsigned jmp_false
, jmp_end
;
375 hres
= compile_expression(ctx
, expr
->expression
);
379 jmp_false
= push_instr(ctx
, OP_jmp_z
);
381 return E_OUTOFMEMORY
;
383 hres
= compile_expression(ctx
, expr
->true_expression
);
387 jmp_end
= push_instr(ctx
, OP_jmp
);
389 return E_OUTOFMEMORY
;
391 instr_ptr(ctx
, jmp_false
)->arg1
.uint
= ctx
->code_off
;
392 if(push_instr(ctx
, OP_pop
) == -1)
393 return E_OUTOFMEMORY
;
395 hres
= compile_expression(ctx
, expr
->false_expression
);
399 instr_ptr(ctx
, jmp_end
)->arg1
.uint
= ctx
->code_off
;
403 static HRESULT
compile_new_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
)
405 unsigned arg_cnt
= 0;
409 hres
= compile_expression(ctx
, expr
->expression
);
413 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
414 hres
= compile_expression(ctx
, arg
->expr
);
420 return push_instr_int(ctx
, OP_new
, arg_cnt
);
423 static HRESULT
compile_interp_fallback(compiler_ctx_t
*ctx
, expression_t
*expr
)
427 instr
= push_instr(ctx
, OP_tree
);
429 return E_OUTOFMEMORY
;
431 instr_ptr(ctx
, instr
)->arg1
.expr
= expr
;
435 static HRESULT
compile_call_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
, BOOL
*no_ret
)
437 unsigned arg_cnt
= 0;
443 if(is_memberid_expr(expr
->expression
->type
)) {
445 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
448 hres
= compile_expression(ctx
, expr
->expression
);
454 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
455 hres
= compile_expression(ctx
, arg
->expr
);
461 instr
= push_instr(ctx
, op
);
463 return E_OUTOFMEMORY
;
465 instr_ptr(ctx
, instr
)->arg1
.uint
= arg_cnt
;
466 instr_ptr(ctx
, instr
)->arg2
.lng
= no_ret
== NULL
;
472 static HRESULT
compile_delete_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
476 switch(expr
->expression
->type
) {
478 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
->expression
;
480 hres
= compile_expression(ctx
, array_expr
->expression1
);
484 hres
= compile_expression(ctx
, array_expr
->expression2
);
488 if(push_instr(ctx
, OP_delete
) == -1)
489 return E_OUTOFMEMORY
;
493 member_expression_t
*member_expr
= (member_expression_t
*)expr
->expression
;
495 hres
= compile_expression(ctx
, member_expr
->expression
);
499 /* FIXME: Potential optimization */
500 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
504 if(push_instr(ctx
, OP_delete
) == -1)
505 return E_OUTOFMEMORY
;
509 return push_instr_bstr(ctx
, OP_delete_ident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
511 const WCHAR fixmeW
[] = {'F','I','X','M','E',0};
513 WARN("invalid delete, unimplemented exception message\n");
515 hres
= compile_expression(ctx
, expr
->expression
);
519 return push_instr_uint_str(ctx
, OP_throw_type
, JS_E_INVALID_DELETE
, fixmeW
);
526 static HRESULT
compile_assign_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
530 if(!is_memberid_expr(expr
->expression1
->type
)) {
531 hres
= compile_expression(ctx
, expr
->expression1
);
535 hres
= compile_expression(ctx
, expr
->expression2
);
539 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
540 return E_OUTOFMEMORY
;
542 return push_instr_uint(ctx
, OP_throw
, JS_E_ILLEGAL_ASSIGN
);
545 hres
= compile_memberid_expression(ctx
, expr
->expression1
, fdexNameEnsure
);
549 if(op
!= OP_LAST
&& push_instr(ctx
, OP_refval
) == -1)
550 return E_OUTOFMEMORY
;
552 hres
= compile_expression(ctx
, expr
->expression2
);
556 if(op
!= OP_LAST
&& push_instr(ctx
, op
) == -1)
557 return E_OUTOFMEMORY
;
559 if(push_instr(ctx
, OP_assign
) == -1)
560 return E_OUTOFMEMORY
;
565 static HRESULT
compile_typeof_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
570 if(is_memberid_expr(expr
->expression
->type
)) {
571 if(expr
->expression
->type
== EXPR_IDENT
)
572 return push_instr_str(ctx
, OP_typeofident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
575 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
578 hres
= compile_expression(ctx
, expr
->expression
);
583 return push_instr(ctx
, op
) == -1 ? E_OUTOFMEMORY
: S_OK
;
586 static HRESULT
compile_literal(compiler_ctx_t
*ctx
, literal_t
*literal
)
588 switch(literal
->type
) {
590 return push_instr_int(ctx
, OP_bool
, literal
->u
.bval
);
592 return push_instr_double(ctx
, OP_double
, literal
->u
.dval
);
594 return push_instr_int(ctx
, OP_int
, literal
->u
.lval
);
596 return push_instr(ctx
, OP_null
);
598 return push_instr_str(ctx
, OP_str
, literal
->u
.wstr
);
603 str
= compiler_alloc(ctx
->code
, (literal
->u
.regexp
.str_len
+1)*sizeof(WCHAR
));
605 return E_OUTOFMEMORY
;
606 memcpy(str
, literal
->u
.regexp
.str
, literal
->u
.regexp
.str_len
*sizeof(WCHAR
));
607 str
[literal
->u
.regexp
.str_len
] = 0;
609 instr
= push_instr(ctx
, OP_regexp
);
611 return E_OUTOFMEMORY
;
613 instr_ptr(ctx
, instr
)->arg1
.str
= str
;
614 instr_ptr(ctx
, instr
)->arg2
.lng
= literal
->u
.regexp
.flags
;
622 static HRESULT
literal_as_bstr(compiler_ctx_t
*ctx
, literal_t
*literal
, BSTR
*str
)
624 switch(literal
->type
) {
626 *str
= compiler_alloc_bstr(ctx
, literal
->u
.wstr
);
629 *str
= int_to_bstr(literal
->u
.lval
);
632 return double_to_bstr(literal
->u
.dval
, str
);
637 return *str
? S_OK
: E_OUTOFMEMORY
;
640 static HRESULT
compile_array_literal(compiler_ctx_t
*ctx
, array_literal_expression_t
*expr
)
642 unsigned i
, elem_cnt
= expr
->length
;
643 array_element_t
*iter
;
646 for(iter
= expr
->element_list
; iter
; iter
= iter
->next
) {
647 elem_cnt
+= iter
->elision
+1;
649 for(i
=0; i
< iter
->elision
; i
++) {
650 if(push_instr(ctx
, OP_undefined
) == -1)
651 return E_OUTOFMEMORY
;
654 hres
= compile_expression(ctx
, iter
->expr
);
659 for(i
=0; i
< expr
->length
; i
++) {
660 if(push_instr(ctx
, OP_undefined
) == -1)
661 return E_OUTOFMEMORY
;
664 return push_instr_uint(ctx
, OP_carray
, elem_cnt
);
667 static HRESULT
compile_object_literal(compiler_ctx_t
*ctx
, property_value_expression_t
*expr
)
674 if(push_instr(ctx
, OP_new_obj
) == -1)
675 return E_OUTOFMEMORY
;
677 for(iter
= expr
->property_list
; iter
; iter
= iter
->next
) {
678 hres
= literal_as_bstr(ctx
, iter
->name
, &name
);
682 hres
= compile_expression(ctx
, iter
->value
);
686 instr
= push_instr(ctx
, OP_obj_prop
);
688 return E_OUTOFMEMORY
;
690 instr_ptr(ctx
, instr
)->arg1
.bstr
= name
;
696 static HRESULT
compile_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
)
700 /* FIXME: not exactly right */
702 return push_instr_bstr(ctx
, OP_ident
, expr
->identifier
);
704 instr
= push_instr(ctx
, OP_func
);
706 return E_OUTOFMEMORY
;
708 instr_ptr(ctx
, instr
)->arg1
.func
= expr
;
712 static HRESULT
compile_expression_noret(compiler_ctx_t
*ctx
, expression_t
*expr
, BOOL
*no_ret
)
716 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
718 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_jmp_z
);
720 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_array
);
722 return compile_array_literal(ctx
, (array_literal_expression_t
*)expr
);
724 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_LAST
);
726 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
728 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
730 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
732 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
734 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
736 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
738 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
739 case EXPR_ASSIGNLSHIFT
:
740 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
741 case EXPR_ASSIGNRSHIFT
:
742 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
743 case EXPR_ASSIGNRRSHIFT
:
744 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
746 return compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
748 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
750 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_bneg
);
752 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
754 return compile_call_expression(ctx
, (call_expression_t
*)expr
, no_ret
);
756 return compile_comma_expression(ctx
, (binary_expression_t
*)expr
);
758 return compile_conditional_expression(ctx
, (conditional_expression_t
*)expr
);
760 return compile_delete_expression(ctx
, (unary_expression_t
*)expr
);
762 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
764 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq
);
766 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq2
);
768 return compile_function_expression(ctx
, (function_expression_t
*)expr
);
770 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
772 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
774 return push_instr_bstr(ctx
, OP_ident
, ((identifier_expression_t
*)expr
)->identifier
);
776 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_in
);
777 case EXPR_INSTANCEOF
:
778 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_instanceof
);
780 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
782 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
784 return compile_literal(ctx
, ((literal_expression_t
*)expr
)->literal
);
786 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
788 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
790 return compile_member_expression(ctx
, (member_expression_t
*)expr
);
792 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_minus
);
794 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
796 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
798 return compile_new_expression(ctx
, (call_expression_t
*)expr
);
800 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq
);
802 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq2
);
804 return compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_jmp_nz
);
806 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_tonum
);
808 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, -1);
810 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, 1);
812 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, -1);
814 return compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, 1);
816 return compile_object_literal(ctx
, (property_value_expression_t
*)expr
);
818 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
820 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
822 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
824 return push_instr(ctx
, OP_this
) == -1 ? E_OUTOFMEMORY
: S_OK
;
826 return compile_typeof_expression(ctx
, (unary_expression_t
*)expr
);
828 return compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_void
);
830 return compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
832 return compile_interp_fallback(ctx
, expr
);
838 static HRESULT
compile_expression(compiler_ctx_t
*ctx
, expression_t
*expr
)
840 return compile_expression_noret(ctx
, expr
, NULL
);
843 void release_bytecode(bytecode_t
*code
)
847 for(i
=0; i
< code
->bstr_cnt
; i
++)
848 SysFreeString(code
->bstr_pool
[i
]);
850 jsheap_free(&code
->heap
);
851 heap_free(code
->bstr_pool
);
852 heap_free(code
->instrs
);
856 void release_compiler(compiler_ctx_t
*ctx
)
861 HRESULT
compile_subscript(parser_ctx_t
*parser
, expression_t
*expr
, BOOL do_ret
, unsigned *ret_off
)
867 parser
->code
= heap_alloc_zero(sizeof(bytecode_t
));
869 return E_OUTOFMEMORY
;
870 jsheap_init(&parser
->code
->heap
);
873 if(!parser
->compiler
) {
874 parser
->compiler
= heap_alloc_zero(sizeof(compiler_ctx_t
));
875 if(!parser
->compiler
)
876 return E_OUTOFMEMORY
;
878 parser
->compiler
->parser
= parser
;
879 parser
->compiler
->code
= parser
->code
;
882 *ret_off
= parser
->compiler
->code_off
;
883 hres
= compile_expression_noret(parser
->compiler
, expr
, do_ret
? NULL
: &no_ret
);
887 return push_instr(parser
->compiler
, OP_ret
) == -1 ? E_OUTOFMEMORY
: S_OK
;