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
21 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas
);
23 typedef struct _statement_ctx_t
{
29 unsigned continue_label
;
31 const labelled_statement_t
*labelled_stat
;
33 struct _statement_ctx_t
*next
;
49 statement_ctx_t
*stat_ctx
;
50 function_code_t
*func
;
52 variable_declaration_t
*var_head
;
53 variable_declaration_t
*var_tail
;
55 function_expression_t
*func_head
;
56 function_expression_t
*func_tail
;
61 instr_arg_type_t arg1_type
;
62 instr_arg_type_t arg2_type
;
64 #define X(n,a,b,c) {#n,b,c},
69 static void dump_instr_arg(instr_arg_type_t type
, instr_arg_t
*arg
)
73 TRACE_(jscript_disas
)("\t%s", debugstr_jsstr(arg
->str
));
76 TRACE_(jscript_disas
)("\t%s", debugstr_wn(arg
->bstr
, SysStringLen(arg
->bstr
)));
79 TRACE_(jscript_disas
)("\t%d", arg
->uint
);
83 TRACE_(jscript_disas
)("\t%u", arg
->uint
);
92 static void dump_code(compiler_ctx_t
*ctx
, unsigned off
)
96 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
97 TRACE_(jscript_disas
)("%d:\t%s", (int)(instr
-ctx
->code
->instrs
), instr_info
[instr
->op
].op_str
);
98 if(instr_info
[instr
->op
].arg1_type
== ARG_DBL
) {
99 TRACE_(jscript_disas
)("\t%lf", instr
->u
.dbl
);
101 dump_instr_arg(instr_info
[instr
->op
].arg1_type
, instr
->u
.arg
);
102 dump_instr_arg(instr_info
[instr
->op
].arg2_type
, instr
->u
.arg
+1);
104 TRACE_(jscript_disas
)("\n");
108 static HRESULT
compile_expression(compiler_ctx_t
*,expression_t
*,BOOL
);
109 static HRESULT
compile_statement(compiler_ctx_t
*,statement_ctx_t
*,statement_t
*);
111 static inline void *compiler_alloc(bytecode_t
*code
, size_t size
)
113 return heap_pool_alloc(&code
->heap
, size
);
116 static jsstr_t
*compiler_alloc_string_len(compiler_ctx_t
*ctx
, const WCHAR
*str
, unsigned len
)
120 if(!ctx
->code
->str_pool_size
) {
121 ctx
->code
->str_pool
= heap_alloc(8 * sizeof(jsstr_t
*));
122 if(!ctx
->code
->str_pool
)
124 ctx
->code
->str_pool_size
= 8;
125 }else if(ctx
->code
->str_pool_size
== ctx
->code
->str_cnt
) {
128 new_pool
= heap_realloc(ctx
->code
->str_pool
, ctx
->code
->str_pool_size
*2*sizeof(jsstr_t
*));
132 ctx
->code
->str_pool
= new_pool
;
133 ctx
->code
->str_pool_size
*= 2;
136 new_str
= jsstr_alloc_len(str
, len
);
140 ctx
->code
->str_pool
[ctx
->code
->str_cnt
++] = new_str
;
144 static jsstr_t
*compiler_alloc_string(compiler_ctx_t
*ctx
, const WCHAR
*str
)
146 return compiler_alloc_string_len(ctx
, str
, strlenW(str
));
149 static BOOL
ensure_bstr_slot(compiler_ctx_t
*ctx
)
151 if(!ctx
->code
->bstr_pool_size
) {
152 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
153 if(!ctx
->code
->bstr_pool
)
155 ctx
->code
->bstr_pool_size
= 8;
156 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
159 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
163 ctx
->code
->bstr_pool
= new_pool
;
164 ctx
->code
->bstr_pool_size
*= 2;
170 static BSTR
compiler_alloc_bstr(compiler_ctx_t
*ctx
, const WCHAR
*str
)
172 if(!ensure_bstr_slot(ctx
))
175 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
176 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
179 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
182 static BSTR
compiler_alloc_bstr_len(compiler_ctx_t
*ctx
, const WCHAR
*str
, size_t len
)
184 if(!ensure_bstr_slot(ctx
))
187 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocStringLen(str
, len
);
188 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
191 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
194 static unsigned push_instr(compiler_ctx_t
*ctx
, jsop_t op
)
196 assert(ctx
->code_size
>= ctx
->code_off
);
198 if(ctx
->code_size
== ctx
->code_off
) {
201 new_instrs
= heap_realloc(ctx
->code
->instrs
, ctx
->code_size
*2*sizeof(instr_t
));
205 ctx
->code
->instrs
= new_instrs
;
209 ctx
->code
->instrs
[ctx
->code_off
].op
= op
;
210 return ctx
->code_off
++;
213 static inline instr_t
*instr_ptr(compiler_ctx_t
*ctx
, unsigned off
)
215 assert(off
< ctx
->code_off
);
216 return ctx
->code
->instrs
+ off
;
219 static HRESULT
push_instr_int(compiler_ctx_t
*ctx
, jsop_t op
, LONG arg
)
223 instr
= push_instr(ctx
, op
);
225 return E_OUTOFMEMORY
;
227 instr_ptr(ctx
, instr
)->u
.arg
->lng
= arg
;
231 static HRESULT
push_instr_str(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
236 str
= compiler_alloc_string(ctx
, arg
);
238 return E_OUTOFMEMORY
;
240 instr
= push_instr(ctx
, op
);
242 return E_OUTOFMEMORY
;
244 instr_ptr(ctx
, instr
)->u
.arg
->str
= str
;
248 static HRESULT
push_instr_bstr(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
253 str
= compiler_alloc_bstr(ctx
, arg
);
255 return E_OUTOFMEMORY
;
257 instr
= push_instr(ctx
, op
);
259 return E_OUTOFMEMORY
;
261 instr_ptr(ctx
, instr
)->u
.arg
->bstr
= str
;
265 static HRESULT
push_instr_bstr_uint(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
270 str
= compiler_alloc_bstr(ctx
, arg1
);
272 return E_OUTOFMEMORY
;
274 instr
= push_instr(ctx
, op
);
276 return E_OUTOFMEMORY
;
278 instr_ptr(ctx
, instr
)->u
.arg
[0].bstr
= str
;
279 instr_ptr(ctx
, instr
)->u
.arg
[1].uint
= arg2
;
283 static HRESULT
push_instr_uint_str(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
288 str
= compiler_alloc_string(ctx
, arg2
);
290 return E_OUTOFMEMORY
;
292 instr
= push_instr(ctx
, op
);
294 return E_OUTOFMEMORY
;
296 instr_ptr(ctx
, instr
)->u
.arg
[0].uint
= arg1
;
297 instr_ptr(ctx
, instr
)->u
.arg
[1].str
= str
;
301 static HRESULT
push_instr_double(compiler_ctx_t
*ctx
, jsop_t op
, double arg
)
305 instr
= push_instr(ctx
, op
);
307 return E_OUTOFMEMORY
;
309 instr_ptr(ctx
, instr
)->u
.dbl
= arg
;
313 static inline void set_arg_uint(compiler_ctx_t
*ctx
, unsigned instr
, unsigned arg
)
315 instr_ptr(ctx
, instr
)->u
.arg
->uint
= arg
;
318 static HRESULT
push_instr_uint(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg
)
322 instr
= push_instr(ctx
, op
);
324 return E_OUTOFMEMORY
;
326 set_arg_uint(ctx
, instr
, arg
);
330 static HRESULT
compile_binary_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
334 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
338 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
342 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
345 static HRESULT
compile_unary_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
)
349 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
353 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
356 /* ECMA-262 3rd Edition 11.2.1 */
357 static HRESULT
compile_member_expression(compiler_ctx_t
*ctx
, member_expression_t
*expr
)
361 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
365 return push_instr_bstr(ctx
, OP_member
, expr
->identifier
);
368 #define LABEL_FLAG 0x80000000
370 static unsigned alloc_label(compiler_ctx_t
*ctx
)
372 if(!ctx
->labels_size
) {
373 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
376 ctx
->labels_size
= 8;
377 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
378 unsigned *new_labels
;
380 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
384 ctx
->labels
= new_labels
;
385 ctx
->labels_size
*= 2;
388 return ctx
->labels_cnt
++ | LABEL_FLAG
;
391 static void label_set_addr(compiler_ctx_t
*ctx
, unsigned label
)
393 assert(label
& LABEL_FLAG
);
394 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->code_off
;
397 static inline BOOL
is_memberid_expr(expression_type_t type
)
399 return type
== EXPR_IDENT
|| type
== EXPR_MEMBER
|| type
== EXPR_ARRAY
;
402 static HRESULT
compile_memberid_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, unsigned flags
)
408 identifier_expression_t
*ident_expr
= (identifier_expression_t
*)expr
;
410 hres
= push_instr_bstr_uint(ctx
, OP_identid
, ident_expr
->identifier
, flags
);
414 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
;
416 hres
= compile_expression(ctx
, array_expr
->expression1
, TRUE
);
420 hres
= compile_expression(ctx
, array_expr
->expression2
, TRUE
);
424 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
428 member_expression_t
*member_expr
= (member_expression_t
*)expr
;
430 hres
= compile_expression(ctx
, member_expr
->expression
, TRUE
);
434 /* FIXME: Potential optimization */
435 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
439 hres
= push_instr_uint(ctx
, OP_memberid
, flags
);
448 static HRESULT
compile_increment_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
, int n
)
452 if(!is_memberid_expr(expr
->expression
->type
)) {
453 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
457 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
460 hres
= compile_memberid_expression(ctx
, expr
->expression
, fdexNameEnsure
);
464 return push_instr_int(ctx
, op
, n
);
467 /* ECMA-262 3rd Edition 11.14 */
468 static HRESULT
compile_comma_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, BOOL emit_ret
)
472 hres
= compile_expression(ctx
, expr
->expression1
, FALSE
);
476 return compile_expression(ctx
, expr
->expression2
, emit_ret
);
479 /* ECMA-262 3rd Edition 11.11 */
480 static HRESULT
compile_logical_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
485 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
489 instr
= push_instr(ctx
, op
);
491 return E_OUTOFMEMORY
;
493 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
497 set_arg_uint(ctx
, instr
, ctx
->code_off
);
501 /* ECMA-262 3rd Edition 11.12 */
502 static HRESULT
compile_conditional_expression(compiler_ctx_t
*ctx
, conditional_expression_t
*expr
)
504 unsigned jmp_false
, jmp_end
;
507 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
511 jmp_false
= push_instr(ctx
, OP_cnd_z
);
513 return E_OUTOFMEMORY
;
515 hres
= compile_expression(ctx
, expr
->true_expression
, TRUE
);
519 jmp_end
= push_instr(ctx
, OP_jmp
);
521 return E_OUTOFMEMORY
;
523 set_arg_uint(ctx
, jmp_false
, ctx
->code_off
);
524 hres
= push_instr_uint(ctx
, OP_pop
, 1);
528 hres
= compile_expression(ctx
, expr
->false_expression
, TRUE
);
532 set_arg_uint(ctx
, jmp_end
, ctx
->code_off
);
536 static HRESULT
compile_new_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
)
538 unsigned arg_cnt
= 0;
542 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
546 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
547 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
553 hres
= push_instr_uint(ctx
, OP_new
, arg_cnt
);
557 hres
= push_instr_uint(ctx
, OP_pop
, arg_cnt
+1);
561 return push_instr(ctx
, OP_push_ret
) ? S_OK
: E_OUTOFMEMORY
;
564 static HRESULT
compile_call_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
, BOOL emit_ret
)
566 unsigned arg_cnt
= 0, extra_args
;
572 if(is_memberid_expr(expr
->expression
->type
)) {
575 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
579 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
585 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
586 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
592 instr
= push_instr(ctx
, op
);
594 return E_OUTOFMEMORY
;
596 instr_ptr(ctx
, instr
)->u
.arg
[0].uint
= arg_cnt
;
597 instr_ptr(ctx
, instr
)->u
.arg
[1].lng
= emit_ret
;
599 hres
= push_instr_uint(ctx
, OP_pop
, arg_cnt
+ extra_args
);
603 return !emit_ret
|| push_instr(ctx
, OP_push_ret
) ? S_OK
: E_OUTOFMEMORY
;
606 static HRESULT
compile_delete_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
610 switch(expr
->expression
->type
) {
612 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
->expression
;
614 hres
= compile_expression(ctx
, array_expr
->expression1
, TRUE
);
618 hres
= compile_expression(ctx
, array_expr
->expression2
, TRUE
);
622 if(!push_instr(ctx
, OP_delete
))
623 return E_OUTOFMEMORY
;
627 member_expression_t
*member_expr
= (member_expression_t
*)expr
->expression
;
629 hres
= compile_expression(ctx
, member_expr
->expression
, TRUE
);
633 /* FIXME: Potential optimization */
634 hres
= push_instr_str(ctx
, OP_str
, member_expr
->identifier
);
638 if(!push_instr(ctx
, OP_delete
))
639 return E_OUTOFMEMORY
;
643 return push_instr_bstr(ctx
, OP_delete_ident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
645 const WCHAR fixmeW
[] = {'F','I','X','M','E',0};
647 WARN("invalid delete, unimplemented exception message\n");
649 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
653 return push_instr_uint_str(ctx
, OP_throw_type
, JS_E_INVALID_DELETE
, fixmeW
);
660 static HRESULT
compile_assign_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
662 BOOL use_throw_path
= FALSE
;
663 unsigned arg_cnt
= 0;
666 if(expr
->expression1
->type
== EXPR_CALL
) {
667 call_expression_t
*call_expr
= (call_expression_t
*)expr
->expression1
;
671 FIXME("op %d not supported on parametrized assign expressions\n", op
);
675 if(is_memberid_expr(call_expr
->expression
->type
) && call_expr
->argument_list
) {
676 hres
= compile_memberid_expression(ctx
, call_expr
->expression
, fdexNameEnsure
);
680 for(arg
= call_expr
->argument_list
; arg
; arg
= arg
->next
) {
681 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
687 use_throw_path
= TRUE
;
689 }else if(is_memberid_expr(expr
->expression1
->type
)) {
690 hres
= compile_memberid_expression(ctx
, expr
->expression1
, fdexNameEnsure
);
694 use_throw_path
= TRUE
;
698 /* Illegal assignment: evaluate and throw */
699 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
703 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
707 if(op
!= OP_LAST
&& !push_instr(ctx
, op
))
708 return E_OUTOFMEMORY
;
710 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
713 if(op
!= OP_LAST
&& !push_instr(ctx
, OP_refval
))
714 return E_OUTOFMEMORY
;
716 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
720 if(op
!= OP_LAST
&& !push_instr(ctx
, op
))
721 return E_OUTOFMEMORY
;
724 return push_instr_uint(ctx
, OP_assign_call
, arg_cnt
);
726 if(!push_instr(ctx
, OP_assign
))
727 return E_OUTOFMEMORY
;
732 static HRESULT
compile_typeof_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
737 if(is_memberid_expr(expr
->expression
->type
)) {
738 if(expr
->expression
->type
== EXPR_IDENT
)
739 return push_instr_bstr(ctx
, OP_typeofident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
742 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
745 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
750 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
753 static HRESULT
compile_literal(compiler_ctx_t
*ctx
, literal_t
*literal
)
755 switch(literal
->type
) {
757 return push_instr_int(ctx
, OP_bool
, literal
->u
.bval
);
759 return push_instr_double(ctx
, OP_double
, literal
->u
.dval
);
761 return push_instr(ctx
, OP_null
) ? S_OK
: E_OUTOFMEMORY
;
763 return push_instr_str(ctx
, OP_str
, literal
->u
.wstr
);
768 str
= compiler_alloc_string_len(ctx
, literal
->u
.regexp
.str
, literal
->u
.regexp
.str_len
);
770 return E_OUTOFMEMORY
;
772 instr
= push_instr(ctx
, OP_regexp
);
774 return E_OUTOFMEMORY
;
776 instr_ptr(ctx
, instr
)->u
.arg
[0].str
= str
;
777 instr_ptr(ctx
, instr
)->u
.arg
[1].uint
= literal
->u
.regexp
.flags
;
785 static HRESULT
literal_as_bstr(compiler_ctx_t
*ctx
, literal_t
*literal
, BSTR
*str
)
787 switch(literal
->type
) {
789 *str
= compiler_alloc_bstr(ctx
, literal
->u
.wstr
);
795 hres
= double_to_string(literal
->u
.dval
, &jsstr
);
799 *str
= compiler_alloc_bstr_len(ctx
, NULL
, jsstr_length(jsstr
));
801 jsstr_flush(jsstr
, *str
);
802 jsstr_release(jsstr
);
808 return *str
? S_OK
: E_OUTOFMEMORY
;
811 static HRESULT
compile_array_literal(compiler_ctx_t
*ctx
, array_literal_expression_t
*expr
)
813 unsigned i
, elem_cnt
= expr
->length
;
814 array_element_t
*iter
;
817 for(iter
= expr
->element_list
; iter
; iter
= iter
->next
) {
818 elem_cnt
+= iter
->elision
+1;
820 for(i
=0; i
< iter
->elision
; i
++) {
821 if(!push_instr(ctx
, OP_undefined
))
822 return E_OUTOFMEMORY
;
825 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
830 for(i
=0; i
< expr
->length
; i
++) {
831 if(!push_instr(ctx
, OP_undefined
))
832 return E_OUTOFMEMORY
;
835 return push_instr_uint(ctx
, OP_carray
, elem_cnt
);
838 static HRESULT
compile_object_literal(compiler_ctx_t
*ctx
, property_value_expression_t
*expr
)
845 if(!push_instr(ctx
, OP_new_obj
))
846 return E_OUTOFMEMORY
;
848 for(iter
= expr
->property_list
; iter
; iter
= iter
->next
) {
849 hres
= literal_as_bstr(ctx
, iter
->name
, &name
);
853 hres
= compile_expression(ctx
, iter
->value
, TRUE
);
857 instr
= push_instr(ctx
, OP_obj_prop
);
859 return E_OUTOFMEMORY
;
861 instr_ptr(ctx
, instr
)->u
.arg
->bstr
= name
;
867 static HRESULT
compile_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
, BOOL emit_ret
)
869 unsigned func_id
= ctx
->func
->func_cnt
++;
870 ctx
->func_tail
= ctx
->func_tail
? (ctx
->func_tail
->next
= expr
) : (ctx
->func_head
= expr
);
871 return emit_ret
? push_instr_uint(ctx
, OP_func
, func_id
) : S_OK
;
874 static HRESULT
compile_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, BOOL emit_ret
)
880 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
883 hres
= compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_z
);
886 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_array
);
889 hres
= compile_array_literal(ctx
, (array_literal_expression_t
*)expr
);
892 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_LAST
);
895 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
898 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
901 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
904 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
907 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
910 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
913 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
915 case EXPR_ASSIGNLSHIFT
:
916 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
918 case EXPR_ASSIGNRSHIFT
:
919 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
921 case EXPR_ASSIGNRRSHIFT
:
922 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
925 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
928 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
931 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_bneg
);
934 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
937 return compile_call_expression(ctx
, (call_expression_t
*)expr
, emit_ret
);
939 return compile_comma_expression(ctx
, (binary_expression_t
*)expr
, emit_ret
);
941 hres
= compile_conditional_expression(ctx
, (conditional_expression_t
*)expr
);
944 hres
= compile_delete_expression(ctx
, (unary_expression_t
*)expr
);
947 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
950 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq
);
953 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq2
);
956 return compile_function_expression(ctx
, (function_expression_t
*)expr
, emit_ret
);
958 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
961 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
964 hres
= push_instr_bstr(ctx
, OP_ident
, ((identifier_expression_t
*)expr
)->identifier
);
967 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_in
);
969 case EXPR_INSTANCEOF
:
970 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_instanceof
);
973 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
976 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
979 hres
= compile_literal(ctx
, ((literal_expression_t
*)expr
)->literal
);
982 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
985 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
988 hres
= compile_member_expression(ctx
, (member_expression_t
*)expr
);
991 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_minus
);
994 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
997 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
1000 hres
= compile_new_expression(ctx
, (call_expression_t
*)expr
);
1003 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq
);
1006 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq2
);
1009 hres
= compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_nz
);
1012 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_tonum
);
1015 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, -1);
1018 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, 1);
1021 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, -1);
1024 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, 1);
1027 hres
= compile_object_literal(ctx
, (property_value_expression_t
*)expr
);
1030 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
1033 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
1036 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
1039 return !emit_ret
|| push_instr(ctx
, OP_this
) ? S_OK
: E_OUTOFMEMORY
;
1041 hres
= compile_typeof_expression(ctx
, (unary_expression_t
*)expr
);
1044 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_void
);
1047 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
1049 DEFAULT_UNREACHABLE
;
1055 return emit_ret
? S_OK
: push_instr_uint(ctx
, OP_pop
, 1);
1058 static inline BOOL
is_loop_statement(statement_type_t type
)
1060 return type
== STAT_FOR
|| type
== STAT_FORIN
|| type
== STAT_WHILE
;
1063 /* ECMA-262 3rd Edition 12.1 */
1064 static HRESULT
compile_block_statement(compiler_ctx_t
*ctx
, statement_t
*iter
)
1069 hres
= compile_statement(ctx
, NULL
, iter
);
1079 /* ECMA-262 3rd Edition 12.2 */
1080 static HRESULT
compile_variable_list(compiler_ctx_t
*ctx
, variable_declaration_t
*list
)
1082 variable_declaration_t
*iter
;
1085 assert(list
!= NULL
);
1088 ctx
->var_tail
->global_next
= list
;
1090 ctx
->var_head
= list
;
1092 for(iter
= list
; iter
; iter
= iter
->next
) {
1093 ctx
->func
->var_cnt
++;
1094 iter
->global_next
= iter
->next
;
1096 ctx
->var_tail
= iter
;
1101 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
1105 hres
= push_instr_bstr(ctx
, OP_var_set
, iter
->identifier
);
1113 /* ECMA-262 3rd Edition 12.2 */
1114 static HRESULT
compile_var_statement(compiler_ctx_t
*ctx
, var_statement_t
*stat
)
1116 return compile_variable_list(ctx
, stat
->variable_list
);
1119 /* ECMA-262 3rd Edition 12.4 */
1120 static HRESULT
compile_expression_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1124 hres
= compile_expression(ctx
, stat
->expr
, ctx
->from_eval
);
1128 return !ctx
->from_eval
|| push_instr(ctx
, OP_setret
) ? S_OK
: E_OUTOFMEMORY
;
1131 /* ECMA-262 3rd Edition 12.5 */
1132 static HRESULT
compile_if_statement(compiler_ctx_t
*ctx
, if_statement_t
*stat
)
1137 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1141 jmp_else
= push_instr(ctx
, OP_jmp_z
);
1143 return E_OUTOFMEMORY
;
1145 hres
= compile_statement(ctx
, NULL
, stat
->if_stat
);
1149 if(stat
->else_stat
) {
1152 jmp_end
= push_instr(ctx
, OP_jmp
);
1154 return E_OUTOFMEMORY
;
1156 set_arg_uint(ctx
, jmp_else
, ctx
->code_off
);
1158 hres
= compile_statement(ctx
, NULL
, stat
->else_stat
);
1162 set_arg_uint(ctx
, jmp_end
, ctx
->code_off
);
1164 set_arg_uint(ctx
, jmp_else
, ctx
->code_off
);
1170 /* ECMA-262 3rd Edition 12.6.2 */
1171 static HRESULT
compile_while_statement(compiler_ctx_t
*ctx
, while_statement_t
*stat
)
1173 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1177 stat_ctx
.break_label
= alloc_label(ctx
);
1178 if(!stat_ctx
.break_label
)
1179 return E_OUTOFMEMORY
;
1181 stat_ctx
.continue_label
= alloc_label(ctx
);
1182 if(!stat_ctx
.continue_label
)
1183 return E_OUTOFMEMORY
;
1185 jmp_off
= ctx
->code_off
;
1187 if(!stat
->do_while
) {
1188 label_set_addr(ctx
, stat_ctx
.continue_label
);
1189 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1193 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1198 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1202 if(stat
->do_while
) {
1203 label_set_addr(ctx
, stat_ctx
.continue_label
);
1204 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1208 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1213 hres
= push_instr_uint(ctx
, OP_jmp
, jmp_off
);
1217 label_set_addr(ctx
, stat_ctx
.break_label
);
1221 /* ECMA-262 3rd Edition 12.6.3 */
1222 static HRESULT
compile_for_statement(compiler_ctx_t
*ctx
, for_statement_t
*stat
)
1224 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1228 if(stat
->variable_list
) {
1229 hres
= compile_variable_list(ctx
, stat
->variable_list
);
1232 }else if(stat
->begin_expr
) {
1233 hres
= compile_expression(ctx
, stat
->begin_expr
, FALSE
);
1238 stat_ctx
.break_label
= alloc_label(ctx
);
1239 if(!stat_ctx
.break_label
)
1240 return E_OUTOFMEMORY
;
1242 stat_ctx
.continue_label
= alloc_label(ctx
);
1243 if(!stat_ctx
.continue_label
)
1244 return E_OUTOFMEMORY
;
1246 expr_off
= ctx
->code_off
;
1249 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1253 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1258 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1262 label_set_addr(ctx
, stat_ctx
.continue_label
);
1264 if(stat
->end_expr
) {
1265 hres
= compile_expression(ctx
, stat
->end_expr
, FALSE
);
1270 hres
= push_instr_uint(ctx
, OP_jmp
, expr_off
);
1274 label_set_addr(ctx
, stat_ctx
.break_label
);
1278 /* ECMA-262 3rd Edition 12.6.4 */
1279 static HRESULT
compile_forin_statement(compiler_ctx_t
*ctx
, forin_statement_t
*stat
)
1281 statement_ctx_t stat_ctx
= {4, FALSE
, FALSE
};
1284 if(stat
->variable
) {
1285 hres
= compile_variable_list(ctx
, stat
->variable
);
1290 stat_ctx
.break_label
= alloc_label(ctx
);
1291 if(!stat_ctx
.break_label
)
1292 return E_OUTOFMEMORY
;
1294 stat_ctx
.continue_label
= alloc_label(ctx
);
1295 if(!stat_ctx
.continue_label
)
1296 return E_OUTOFMEMORY
;
1298 hres
= compile_expression(ctx
, stat
->in_expr
, TRUE
);
1302 if(stat
->variable
) {
1303 hres
= push_instr_bstr_uint(ctx
, OP_identid
, stat
->variable
->identifier
, fdexNameEnsure
);
1306 }else if(is_memberid_expr(stat
->expr
->type
)) {
1307 hres
= compile_memberid_expression(ctx
, stat
->expr
, fdexNameEnsure
);
1311 hres
= push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
1315 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1319 hres
= push_instr_int(ctx
, OP_int
, DISPID_STARTENUM
);
1323 label_set_addr(ctx
, stat_ctx
.continue_label
);
1324 hres
= push_instr_uint(ctx
, OP_forin
, stat_ctx
.break_label
);
1326 return E_OUTOFMEMORY
;
1328 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1332 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.continue_label
);
1336 label_set_addr(ctx
, stat_ctx
.break_label
);
1340 static HRESULT
pop_to_stat(compiler_ctx_t
*ctx
, BOOL var_stack
, BOOL scope_stack
, statement_ctx_t
*stat_ctx
)
1342 unsigned stack_pop
= 0;
1343 statement_ctx_t
*iter
;
1345 for(iter
= ctx
->stat_ctx
; iter
!= stat_ctx
; iter
= iter
->next
) {
1347 if(iter
->using_scope
&& !push_instr(ctx
, OP_pop_scope
))
1348 return E_OUTOFMEMORY
;
1349 if(iter
->using_except
&& !push_instr(ctx
, OP_pop_except
))
1350 return E_OUTOFMEMORY
;
1352 stack_pop
+= iter
->stack_use
;
1355 if(var_stack
&& stack_pop
) {
1358 hres
= push_instr_uint(ctx
, OP_pop
, stack_pop
);
1366 /* ECMA-262 3rd Edition 12.7 */
1367 static HRESULT
compile_continue_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1369 statement_ctx_t
*pop_ctx
;
1372 if(stat
->identifier
) {
1373 statement_t
*label_stat
;
1374 statement_ctx_t
*iter
;
1378 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1379 if(iter
->continue_label
)
1381 if(iter
->labelled_stat
&& !strcmpW(iter
->labelled_stat
->identifier
, stat
->identifier
))
1386 WARN("Label not found\n");
1387 return JS_E_LABEL_NOT_FOUND
;
1390 /* Labelled continue are allowed only on loops */
1391 for(label_stat
= iter
->labelled_stat
->statement
;
1392 label_stat
->type
== STAT_LABEL
;
1393 label_stat
= ((labelled_statement_t
*)label_stat
)->statement
);
1394 if(!is_loop_statement(label_stat
->type
)) {
1395 WARN("Label is not a loop\n");
1396 return JS_E_INVALID_CONTINUE
;
1399 assert(pop_ctx
!= NULL
);
1401 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1402 if(pop_ctx
->continue_label
)
1407 WARN("continue outside loop\n");
1408 return JS_E_INVALID_CONTINUE
;
1412 hres
= pop_to_stat(ctx
, TRUE
, TRUE
, pop_ctx
);
1416 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->continue_label
);
1419 /* ECMA-262 3rd Edition 12.8 */
1420 static HRESULT
compile_break_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1422 statement_ctx_t
*pop_ctx
;
1425 if(stat
->identifier
) {
1426 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1427 if(pop_ctx
->labelled_stat
&& !strcmpW(pop_ctx
->labelled_stat
->identifier
, stat
->identifier
)) {
1428 assert(pop_ctx
->break_label
);
1434 WARN("Label not found\n");
1435 return JS_E_LABEL_NOT_FOUND
;
1438 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1439 if(pop_ctx
->break_label
&& !pop_ctx
->labelled_stat
)
1444 WARN("Break outside loop\n");
1445 return JS_E_INVALID_BREAK
;
1449 hres
= pop_to_stat(ctx
, TRUE
, TRUE
, pop_ctx
->next
);
1453 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->break_label
);
1456 /* ECMA-262 3rd Edition 12.9 */
1457 static HRESULT
compile_return_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1461 if(ctx
->from_eval
) {
1462 WARN("misplaced return statement\n");
1463 return JS_E_MISPLACED_RETURN
;
1466 hres
= pop_to_stat(ctx
, TRUE
, FALSE
, NULL
);
1471 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1474 if(!push_instr(ctx
, OP_setret
))
1475 return E_OUTOFMEMORY
;
1478 hres
= pop_to_stat(ctx
, FALSE
, TRUE
, NULL
);
1482 return push_instr_uint(ctx
, OP_ret
, !stat
->expr
);
1485 /* ECMA-262 3rd Edition 12.10 */
1486 static HRESULT
compile_with_statement(compiler_ctx_t
*ctx
, with_statement_t
*stat
)
1488 statement_ctx_t stat_ctx
= {0, TRUE
, FALSE
};
1491 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1495 if(!push_instr(ctx
, OP_push_scope
))
1496 return E_OUTOFMEMORY
;
1498 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1502 if(!push_instr(ctx
, OP_pop_scope
))
1503 return E_OUTOFMEMORY
;
1508 /* ECMA-262 3rd Edition 12.10 */
1509 static HRESULT
compile_labelled_statement(compiler_ctx_t
*ctx
, labelled_statement_t
*stat
)
1511 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
, 0, 0, stat
}, *iter
;
1514 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1515 if(iter
->labelled_stat
&& !strcmpW(iter
->labelled_stat
->identifier
, stat
->identifier
)) {
1516 WARN("Label %s redefined\n", debugstr_w(stat
->identifier
));
1517 return JS_E_LABEL_REDEFINED
;
1521 /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1522 stat_ctx
.break_label
= alloc_label(ctx
);
1523 if(!stat_ctx
.break_label
)
1524 return E_OUTOFMEMORY
;
1526 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1530 label_set_addr(ctx
, stat_ctx
.break_label
);
1534 /* ECMA-262 3rd Edition 12.13 */
1535 static HRESULT
compile_switch_statement(compiler_ctx_t
*ctx
, switch_statement_t
*stat
)
1537 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1538 unsigned case_cnt
= 0, *case_jmps
, i
, default_jmp
;
1539 BOOL have_default
= FALSE
;
1540 statement_t
*stat_iter
;
1541 case_clausule_t
*iter
;
1544 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1548 stat_ctx
.break_label
= alloc_label(ctx
);
1549 if(!stat_ctx
.break_label
)
1550 return E_OUTOFMEMORY
;
1552 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1557 case_jmps
= heap_alloc(case_cnt
* sizeof(*case_jmps
));
1559 return E_OUTOFMEMORY
;
1562 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1564 have_default
= TRUE
;
1568 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
1572 case_jmps
[i
] = push_instr(ctx
, OP_case
);
1574 hres
= E_OUTOFMEMORY
;
1580 if(SUCCEEDED(hres
)) {
1581 hres
= push_instr_uint(ctx
, OP_pop
, 1);
1582 if(SUCCEEDED(hres
)) {
1583 default_jmp
= push_instr(ctx
, OP_jmp
);
1585 hres
= E_OUTOFMEMORY
;
1590 heap_free(case_jmps
);
1595 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1596 while(iter
->next
&& iter
->next
->stat
== iter
->stat
) {
1597 set_arg_uint(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
, ctx
->code_off
);
1601 set_arg_uint(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
, ctx
->code_off
);
1603 for(stat_iter
= iter
->stat
; stat_iter
&& (!iter
->next
|| iter
->next
->stat
!= stat_iter
);
1604 stat_iter
= stat_iter
->next
) {
1605 hres
= compile_statement(ctx
, &stat_ctx
, stat_iter
);
1613 heap_free(case_jmps
);
1616 assert(i
== case_cnt
);
1619 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.break_label
);
1622 set_arg_uint(ctx
, default_jmp
, ctx
->code_off
);
1625 label_set_addr(ctx
, stat_ctx
.break_label
);
1629 /* ECMA-262 3rd Edition 12.13 */
1630 static HRESULT
compile_throw_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1634 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1638 return push_instr(ctx
, OP_throw
) ? S_OK
: E_OUTOFMEMORY
;
1641 /* ECMA-262 3rd Edition 12.14 */
1642 static HRESULT
compile_try_statement(compiler_ctx_t
*ctx
, try_statement_t
*stat
)
1644 statement_ctx_t try_ctx
= {0, FALSE
, TRUE
}, catch_ctx
= {0, TRUE
, FALSE
};
1645 statement_ctx_t finally_ctx
= {2, FALSE
, FALSE
};
1646 unsigned push_except
;
1650 push_except
= push_instr(ctx
, OP_push_except
);
1652 return E_OUTOFMEMORY
;
1654 if(stat
->catch_block
) {
1655 ident
= compiler_alloc_bstr(ctx
, stat
->catch_block
->identifier
);
1657 return E_OUTOFMEMORY
;
1662 instr_ptr(ctx
, push_except
)->u
.arg
[1].bstr
= ident
;
1664 if(!stat
->catch_block
)
1665 try_ctx
.stack_use
= 2;
1667 hres
= compile_statement(ctx
, &try_ctx
, stat
->try_statement
);
1671 if(!push_instr(ctx
, OP_pop_except
))
1672 return E_OUTOFMEMORY
;
1674 if(stat
->catch_block
) {
1675 unsigned jmp_finally
;
1677 jmp_finally
= push_instr(ctx
, OP_jmp
);
1679 return E_OUTOFMEMORY
;
1681 instr_ptr(ctx
, push_except
)->u
.arg
[0].uint
= ctx
->code_off
;
1683 hres
= compile_statement(ctx
, &catch_ctx
, stat
->catch_block
->statement
);
1687 if(!push_instr(ctx
, OP_pop_scope
))
1688 return E_OUTOFMEMORY
;
1690 set_arg_uint(ctx
, jmp_finally
, ctx
->code_off
);
1692 set_arg_uint(ctx
, push_except
, ctx
->code_off
);
1695 if(stat
->finally_statement
) {
1696 hres
= compile_statement(ctx
, stat
->catch_block
? NULL
: &finally_ctx
, stat
->finally_statement
);
1700 if(!stat
->catch_block
&& !push_instr(ctx
, OP_end_finally
))
1701 return E_OUTOFMEMORY
;
1707 static HRESULT
compile_statement(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
1712 stat_ctx
->next
= ctx
->stat_ctx
;
1713 ctx
->stat_ctx
= stat_ctx
;
1716 switch(stat
->type
) {
1718 hres
= compile_block_statement(ctx
, ((block_statement_t
*)stat
)->stat_list
);
1721 hres
= compile_break_statement(ctx
, (branch_statement_t
*)stat
);
1724 hres
= compile_continue_statement(ctx
, (branch_statement_t
*)stat
);
1731 hres
= compile_expression_statement(ctx
, (expression_statement_t
*)stat
);
1734 hres
= compile_for_statement(ctx
, (for_statement_t
*)stat
);
1737 hres
= compile_forin_statement(ctx
, (forin_statement_t
*)stat
);
1740 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
1743 hres
= compile_labelled_statement(ctx
, (labelled_statement_t
*)stat
);
1746 hres
= compile_return_statement(ctx
, (expression_statement_t
*)stat
);
1749 hres
= compile_switch_statement(ctx
, (switch_statement_t
*)stat
);
1752 hres
= compile_throw_statement(ctx
, (expression_statement_t
*)stat
);
1755 hres
= compile_try_statement(ctx
, (try_statement_t
*)stat
);
1758 hres
= compile_var_statement(ctx
, (var_statement_t
*)stat
);
1761 hres
= compile_while_statement(ctx
, (while_statement_t
*)stat
);
1764 hres
= compile_with_statement(ctx
, (with_statement_t
*)stat
);
1766 DEFAULT_UNREACHABLE
;
1770 assert(ctx
->stat_ctx
== stat_ctx
);
1771 ctx
->stat_ctx
= stat_ctx
->next
;
1777 static void resolve_labels(compiler_ctx_t
*ctx
, unsigned off
)
1781 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
1782 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->u
.arg
->uint
& LABEL_FLAG
)) {
1783 assert((instr
->u
.arg
->uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
1784 instr
->u
.arg
->uint
= ctx
->labels
[instr
->u
.arg
->uint
& ~LABEL_FLAG
];
1786 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
1789 ctx
->labels_cnt
= 0;
1792 void release_bytecode(bytecode_t
*code
)
1799 for(i
=0; i
< code
->bstr_cnt
; i
++)
1800 SysFreeString(code
->bstr_pool
[i
]);
1801 for(i
=0; i
< code
->str_cnt
; i
++)
1802 jsstr_release(code
->str_pool
[i
]);
1804 heap_free(code
->source
);
1805 heap_pool_free(&code
->heap
);
1806 heap_free(code
->bstr_pool
);
1807 heap_free(code
->str_pool
);
1808 heap_free(code
->instrs
);
1812 static HRESULT
init_code(compiler_ctx_t
*compiler
, const WCHAR
*source
)
1814 compiler
->code
= heap_alloc_zero(sizeof(bytecode_t
));
1816 return E_OUTOFMEMORY
;
1818 compiler
->code
->ref
= 1;
1819 heap_pool_init(&compiler
->code
->heap
);
1821 compiler
->code
->source
= heap_strdupW(source
);
1822 if(!compiler
->code
->source
) {
1823 release_bytecode(compiler
->code
);
1824 return E_OUTOFMEMORY
;
1827 compiler
->code
->instrs
= heap_alloc(64 * sizeof(instr_t
));
1828 if(!compiler
->code
->instrs
) {
1829 release_bytecode(compiler
->code
);
1830 return E_OUTOFMEMORY
;
1833 compiler
->code_size
= 64;
1834 compiler
->code_off
= 1;
1838 static HRESULT
compile_function(compiler_ctx_t
*ctx
, source_elements_t
*source
, function_expression_t
*func_expr
,
1839 BOOL from_eval
, function_code_t
*func
)
1841 variable_declaration_t
*var_iter
;
1842 function_expression_t
*iter
;
1848 ctx
->var_head
= ctx
->var_tail
= NULL
;
1849 ctx
->func_head
= ctx
->func_tail
= NULL
;
1850 ctx
->from_eval
= from_eval
;
1852 off
= ctx
->code_off
;
1854 hres
= compile_block_statement(ctx
, source
->statement
);
1858 resolve_labels(ctx
, off
);
1860 hres
= push_instr_uint(ctx
, OP_ret
, !from_eval
);
1864 if(TRACE_ON(jscript_disas
))
1865 dump_code(ctx
, off
);
1867 func
->instr_off
= off
;
1870 if(func_expr
->identifier
) {
1871 func
->name
= compiler_alloc_bstr(ctx
, func_expr
->identifier
);
1873 return E_OUTOFMEMORY
;
1876 if(func_expr
->event_target
) {
1877 func
->event_target
= compiler_alloc_bstr(ctx
, func_expr
->event_target
);
1878 if(!func
->event_target
)
1879 return E_OUTOFMEMORY
;
1884 parameter_t
*param_iter
;
1886 func
->source
= func_expr
->src_str
;
1887 func
->source_len
= func_expr
->src_len
;
1889 for(param_iter
= func_expr
->parameter_list
; param_iter
; param_iter
= param_iter
->next
)
1892 func
->params
= compiler_alloc(ctx
->code
, func
->param_cnt
* sizeof(*func
->params
));
1894 return E_OUTOFMEMORY
;
1896 for(param_iter
= func_expr
->parameter_list
, i
=0; param_iter
; param_iter
= param_iter
->next
, i
++) {
1897 func
->params
[i
] = compiler_alloc_bstr(ctx
, param_iter
->identifier
);
1898 if(!func
->params
[i
])
1899 return E_OUTOFMEMORY
;
1903 func
->variables
= compiler_alloc(ctx
->code
, func
->var_cnt
* sizeof(*func
->variables
));
1904 if(!func
->variables
)
1905 return E_OUTOFMEMORY
;
1907 for(var_iter
= ctx
->var_head
, i
=0; var_iter
; var_iter
= var_iter
->global_next
, i
++) {
1908 func
->variables
[i
] = compiler_alloc_bstr(ctx
, var_iter
->identifier
);
1909 if(!func
->variables
[i
])
1910 return E_OUTOFMEMORY
;
1913 assert(i
== func
->var_cnt
);
1915 func
->funcs
= compiler_alloc(ctx
->code
, func
->func_cnt
* sizeof(*func
->funcs
));
1917 return E_OUTOFMEMORY
;
1918 memset(func
->funcs
, 0, func
->func_cnt
* sizeof(*func
->funcs
));
1920 for(iter
= ctx
->func_head
, i
=0; iter
; iter
= iter
->next
, i
++) {
1921 hres
= compile_function(ctx
, iter
->source_elements
, iter
, FALSE
, func
->funcs
+i
);
1926 assert(i
== func
->func_cnt
);
1931 static HRESULT
parse_arguments(compiler_ctx_t
*ctx
, const WCHAR
*args
, BSTR
*arg_array
, unsigned *args_size
)
1933 const WCHAR
*ptr
= args
, *ptr2
;
1934 unsigned arg_cnt
= 0;
1936 while(isspaceW(*ptr
))
1945 if(!isalphaW(*ptr
) && *ptr
!= '_') {
1946 FIXME("expected alpha or '_': %s\n", debugstr_w(ptr
));
1951 while(isalnumW(*ptr
) || *ptr
== '_')
1954 if(*ptr
&& *ptr
!= ',' && !isspaceW(*ptr
)) {
1955 FIXME("unexpected har %s\n", debugstr_w(ptr
));
1960 arg_array
[arg_cnt
] = compiler_alloc_bstr_len(ctx
, ptr2
, ptr
-ptr2
);
1961 if(!arg_array
[arg_cnt
])
1962 return E_OUTOFMEMORY
;
1966 while(isspaceW(*ptr
))
1971 FIXME("expected ',': %s\n", debugstr_w(ptr
));
1976 while(isspaceW(*ptr
))
1981 *args_size
= arg_cnt
;
1985 static HRESULT
compile_arguments(compiler_ctx_t
*ctx
, const WCHAR
*args
)
1989 hres
= parse_arguments(ctx
, args
, NULL
, &ctx
->code
->global_code
.param_cnt
);
1993 ctx
->code
->global_code
.params
= compiler_alloc(ctx
->code
,
1994 ctx
->code
->global_code
.param_cnt
* sizeof(*ctx
->code
->global_code
.params
));
1995 if(!ctx
->code
->global_code
.params
)
1996 return E_OUTOFMEMORY
;
1998 return parse_arguments(ctx
, args
, ctx
->code
->global_code
.params
, NULL
);
2001 HRESULT
compile_script(script_ctx_t
*ctx
, const WCHAR
*code
, const WCHAR
*args
, const WCHAR
*delimiter
,
2002 BOOL from_eval
, BOOL use_decode
, bytecode_t
**ret
)
2004 compiler_ctx_t compiler
= {0};
2007 hres
= init_code(&compiler
, code
);
2012 hres
= compile_arguments(&compiler
, args
);
2018 hres
= decode_source(compiler
.code
->source
);
2020 WARN("Decoding failed\n");
2025 hres
= script_parse(ctx
, compiler
.code
->source
, delimiter
, from_eval
, &compiler
.parser
);
2027 release_bytecode(compiler
.code
);
2031 hres
= compile_function(&compiler
, compiler
.parser
->source
, NULL
, from_eval
, &compiler
.code
->global_code
);
2032 parser_release(compiler
.parser
);
2034 release_bytecode(compiler
.code
);
2038 *ret
= compiler
.code
;