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
26 #include "wine/rbtree.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
30 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas
);
32 typedef struct _statement_ctx_t
{
38 unsigned continue_label
;
40 const labelled_statement_t
*labelled_stat
;
42 unsigned int scope_index
;
44 BOOL scope_has_functions
;
45 struct _statement_ctx_t
*next
;
49 struct wine_rb_entry entry
;
54 typedef struct _compiler_ctx_t
{
69 struct wine_rb_tree locals
;
70 unsigned int locals_cnt
;
71 unsigned int *ref_index
;
74 unsigned local_scope_count
;
75 unsigned local_scope_size
;
77 statement_ctx_t
*stat_ctx
;
78 function_code_t
*func
;
82 function_expression_t
*func_head
;
83 function_expression_t
*func_tail
;
84 function_expression_t
*current_function_expr
;
91 instr_arg_type_t arg1_type
;
92 instr_arg_type_t arg2_type
;
94 #define X(n,a,b,c) {#n,b,c},
99 static void dump_instr_arg(instr_arg_type_t type
, instr_arg_t
*arg
)
103 TRACE_(jscript_disas
)("\t%s", debugstr_jsstr(arg
->str
));
106 TRACE_(jscript_disas
)("\t%s", debugstr_wn(arg
->bstr
, SysStringLen(arg
->bstr
)));
109 TRACE_(jscript_disas
)("\t%d", arg
->uint
);
113 TRACE_(jscript_disas
)("\t%u", arg
->uint
);
122 static void dump_code(compiler_ctx_t
*ctx
, unsigned off
)
126 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
127 TRACE_(jscript_disas
)("%d:\t%s", (int)(instr
-ctx
->code
->instrs
), instr_info
[instr
->op
].op_str
);
128 if(instr_info
[instr
->op
].arg1_type
== ARG_DBL
) {
129 TRACE_(jscript_disas
)("\t%lf", instr
->u
.dbl
);
131 dump_instr_arg(instr_info
[instr
->op
].arg1_type
, instr
->u
.arg
);
132 dump_instr_arg(instr_info
[instr
->op
].arg2_type
, instr
->u
.arg
+1);
134 TRACE_(jscript_disas
)("\n");
138 static HRESULT
compile_expression(compiler_ctx_t
*,expression_t
*,BOOL
);
139 static HRESULT
compile_statement(compiler_ctx_t
*,statement_ctx_t
*,statement_t
*);
141 static int function_local_cmp(const void *key
, const struct wine_rb_entry
*entry
)
143 function_local_t
*local
= WINE_RB_ENTRY_VALUE(entry
, function_local_t
, entry
);
144 return wcscmp(key
, local
->name
);
147 static BOOL
alloc_local_scope(compiler_ctx_t
*ctx
, unsigned int *scope_index
)
149 unsigned int scope
, new_size
;
152 scope
= ctx
->local_scope_count
++;
153 if (scope
== ctx
->local_scope_size
)
155 new_size
= max(1, ctx
->local_scope_size
* 2);
156 if (!(new_alloc
= heap_realloc(ctx
->local_scopes
, new_size
* sizeof(*ctx
->local_scopes
))))
158 ctx
->local_scopes
= new_alloc
;
159 ctx
->local_scope_size
= new_size
;
162 ctx
->local_scopes
[scope
].locals_cnt
= 0;
163 ctx
->local_scopes
[scope
].ref_index
= scope_index
;
164 wine_rb_init(&ctx
->local_scopes
[scope
].locals
, function_local_cmp
);
165 *scope_index
= scope
;
170 static void remove_local_scope(compiler_ctx_t
*ctx
, unsigned int scope_index
)
174 assert(scope_index
< ctx
->local_scope_count
);
175 --ctx
->local_scope_count
;
176 assert(scope_index
== *ctx
->local_scopes
[scope_index
].ref_index
);
177 *ctx
->local_scopes
[scope_index
].ref_index
= 0;
178 memmove(&ctx
->local_scopes
[scope_index
], &ctx
->local_scopes
[scope_index
+ 1],
179 sizeof(*ctx
->local_scopes
) * (ctx
->local_scope_count
- scope_index
));
180 for (i
= scope_index
; i
< ctx
->local_scope_count
; ++i
)
181 --*ctx
->local_scopes
[i
].ref_index
;
184 static inline void *compiler_alloc(bytecode_t
*code
, size_t size
)
186 return heap_pool_alloc(&code
->heap
, size
);
189 jsstr_t
*compiler_alloc_string_len(compiler_ctx_t
*ctx
, const WCHAR
*str
, unsigned len
)
193 if(!ctx
->code
->str_pool_size
) {
194 ctx
->code
->str_pool
= heap_alloc(8 * sizeof(jsstr_t
*));
195 if(!ctx
->code
->str_pool
)
197 ctx
->code
->str_pool_size
= 8;
198 }else if(ctx
->code
->str_pool_size
== ctx
->code
->str_cnt
) {
201 new_pool
= heap_realloc(ctx
->code
->str_pool
, ctx
->code
->str_pool_size
*2*sizeof(jsstr_t
*));
205 ctx
->code
->str_pool
= new_pool
;
206 ctx
->code
->str_pool_size
*= 2;
209 new_str
= jsstr_alloc_len(str
, len
);
213 ctx
->code
->str_pool
[ctx
->code
->str_cnt
++] = new_str
;
217 static jsstr_t
*compiler_alloc_string(compiler_ctx_t
*ctx
, const WCHAR
*str
)
219 return compiler_alloc_string_len(ctx
, str
, lstrlenW(str
));
222 static BOOL
ensure_bstr_slot(compiler_ctx_t
*ctx
)
224 if(!ctx
->code
->bstr_pool_size
) {
225 ctx
->code
->bstr_pool
= heap_alloc(8 * sizeof(BSTR
));
226 if(!ctx
->code
->bstr_pool
)
228 ctx
->code
->bstr_pool_size
= 8;
229 }else if(ctx
->code
->bstr_pool_size
== ctx
->code
->bstr_cnt
) {
232 new_pool
= heap_realloc(ctx
->code
->bstr_pool
, ctx
->code
->bstr_pool_size
*2*sizeof(BSTR
));
236 ctx
->code
->bstr_pool
= new_pool
;
237 ctx
->code
->bstr_pool_size
*= 2;
243 static BSTR
compiler_alloc_bstr(compiler_ctx_t
*ctx
, const WCHAR
*str
)
245 if(!ensure_bstr_slot(ctx
))
248 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocString(str
);
249 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
252 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
255 static BSTR
compiler_alloc_bstr_len(compiler_ctx_t
*ctx
, const WCHAR
*str
, size_t len
)
257 if(!ensure_bstr_slot(ctx
))
260 ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
] = SysAllocStringLen(str
, len
);
261 if(!ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
])
264 return ctx
->code
->bstr_pool
[ctx
->code
->bstr_cnt
++];
267 void set_compiler_loc(compiler_ctx_t
*ctx
, unsigned loc
)
272 static unsigned push_instr(compiler_ctx_t
*ctx
, jsop_t op
)
274 assert(ctx
->code_size
>= ctx
->code_off
);
276 if(ctx
->code_size
== ctx
->code_off
) {
279 new_instrs
= heap_realloc(ctx
->code
->instrs
, ctx
->code_size
*2*sizeof(instr_t
));
283 ctx
->code
->instrs
= new_instrs
;
287 ctx
->code
->instrs
[ctx
->code_off
].op
= op
;
288 ctx
->code
->instrs
[ctx
->code_off
].loc
= ctx
->loc
;
289 return ctx
->code_off
++;
292 static inline instr_t
*instr_ptr(compiler_ctx_t
*ctx
, unsigned off
)
294 assert(off
< ctx
->code_off
);
295 return ctx
->code
->instrs
+ off
;
298 static HRESULT
push_instr_int(compiler_ctx_t
*ctx
, jsop_t op
, LONG arg
)
302 instr
= push_instr(ctx
, op
);
304 return E_OUTOFMEMORY
;
306 instr_ptr(ctx
, instr
)->u
.arg
->lng
= arg
;
310 static HRESULT
push_instr_str(compiler_ctx_t
*ctx
, jsop_t op
, jsstr_t
*str
)
314 instr
= push_instr(ctx
, op
);
316 return E_OUTOFMEMORY
;
318 instr_ptr(ctx
, instr
)->u
.arg
->str
= str
;
322 static HRESULT
push_instr_str_uint(compiler_ctx_t
*ctx
, jsop_t op
, jsstr_t
*str
, unsigned arg2
)
326 instr
= push_instr(ctx
, op
);
328 return E_OUTOFMEMORY
;
330 instr_ptr(ctx
, instr
)->u
.arg
[0].str
= str
;
331 instr_ptr(ctx
, instr
)->u
.arg
[1].uint
= arg2
;
335 static HRESULT
push_instr_bstr(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg
)
340 str
= compiler_alloc_bstr(ctx
, arg
);
342 return E_OUTOFMEMORY
;
344 instr
= push_instr(ctx
, op
);
346 return E_OUTOFMEMORY
;
348 instr_ptr(ctx
, instr
)->u
.arg
->bstr
= str
;
352 static HRESULT
push_instr_bstr_uint(compiler_ctx_t
*ctx
, jsop_t op
, const WCHAR
*arg1
, unsigned arg2
)
357 str
= compiler_alloc_bstr(ctx
, arg1
);
359 return E_OUTOFMEMORY
;
361 instr
= push_instr(ctx
, op
);
363 return E_OUTOFMEMORY
;
365 instr_ptr(ctx
, instr
)->u
.arg
[0].bstr
= str
;
366 instr_ptr(ctx
, instr
)->u
.arg
[1].uint
= arg2
;
370 static HRESULT
push_instr_uint_str(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg1
, const WCHAR
*arg2
)
375 str
= compiler_alloc_string(ctx
, arg2
);
377 return E_OUTOFMEMORY
;
379 instr
= push_instr(ctx
, op
);
381 return E_OUTOFMEMORY
;
383 instr_ptr(ctx
, instr
)->u
.arg
[0].uint
= arg1
;
384 instr_ptr(ctx
, instr
)->u
.arg
[1].str
= str
;
388 static HRESULT
push_instr_double(compiler_ctx_t
*ctx
, jsop_t op
, double arg
)
392 instr
= push_instr(ctx
, op
);
394 return E_OUTOFMEMORY
;
396 instr_ptr(ctx
, instr
)->u
.dbl
= arg
;
400 static inline void set_arg_uint(compiler_ctx_t
*ctx
, unsigned instr
, unsigned arg
)
402 instr_ptr(ctx
, instr
)->u
.arg
->uint
= arg
;
405 static HRESULT
push_instr_uint(compiler_ctx_t
*ctx
, jsop_t op
, unsigned arg
)
409 instr
= push_instr(ctx
, op
);
411 return E_OUTOFMEMORY
;
413 set_arg_uint(ctx
, instr
, arg
);
417 static HRESULT
compile_binary_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
421 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
425 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
429 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
432 static HRESULT
compile_unary_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
)
436 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
440 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
443 /* ECMA-262 3rd Edition 11.2.1 */
444 static HRESULT
compile_member_expression(compiler_ctx_t
*ctx
, member_expression_t
*expr
)
448 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
452 return push_instr_bstr(ctx
, OP_member
, expr
->identifier
);
455 #define LABEL_FLAG 0x80000000
457 static unsigned alloc_label(compiler_ctx_t
*ctx
)
459 if(!ctx
->labels_size
) {
460 ctx
->labels
= heap_alloc(8 * sizeof(*ctx
->labels
));
463 ctx
->labels_size
= 8;
464 }else if(ctx
->labels_size
== ctx
->labels_cnt
) {
465 unsigned *new_labels
;
467 new_labels
= heap_realloc(ctx
->labels
, 2*ctx
->labels_size
*sizeof(*ctx
->labels
));
471 ctx
->labels
= new_labels
;
472 ctx
->labels_size
*= 2;
475 return ctx
->labels_cnt
++ | LABEL_FLAG
;
478 static void label_set_addr(compiler_ctx_t
*ctx
, unsigned label
)
480 assert(label
& LABEL_FLAG
);
481 ctx
->labels
[label
& ~LABEL_FLAG
] = ctx
->code_off
;
484 static inline BOOL
is_memberid_expr(expression_type_t type
)
486 return type
== EXPR_IDENT
|| type
== EXPR_MEMBER
|| type
== EXPR_ARRAY
;
489 static BOOL
bind_local(compiler_ctx_t
*ctx
, const WCHAR
*identifier
, int *ret_ref
)
491 statement_ctx_t
*iter
;
494 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
495 if(iter
->using_scope
)
497 if (!iter
->block_scope
)
500 if ((ref
= lookup_local(ctx
->func
, identifier
, iter
->scope_index
)))
508 ref
= lookup_local(ctx
->func
, identifier
, 0);
516 static HRESULT
emit_identifier_ref(compiler_ctx_t
*ctx
, const WCHAR
*identifier
, unsigned flags
)
519 if(bind_local(ctx
, identifier
, &local_ref
))
520 return push_instr_int(ctx
, OP_local_ref
, local_ref
);
521 return push_instr_bstr_uint(ctx
, OP_identid
, identifier
, flags
);
524 static HRESULT
emit_identifier(compiler_ctx_t
*ctx
, const WCHAR
*identifier
)
527 if(bind_local(ctx
, identifier
, &local_ref
))
528 return push_instr_int(ctx
, OP_local
, local_ref
);
529 return push_instr_bstr(ctx
, OP_ident
, identifier
);
532 static HRESULT
emit_member_expression(compiler_ctx_t
*ctx
, expression_t
*expr
)
536 if(expr
->type
== EXPR_ARRAY
) {
537 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
;
539 hres
= compile_expression(ctx
, array_expr
->expression1
, TRUE
);
543 hres
= compile_expression(ctx
, array_expr
->expression2
, TRUE
);
547 if(!push_instr(ctx
, OP_to_string
))
548 return E_OUTOFMEMORY
;
550 member_expression_t
*member_expr
= (member_expression_t
*)expr
;
553 assert(expr
->type
== EXPR_MEMBER
);
555 hres
= compile_expression(ctx
, member_expr
->expression
, TRUE
);
559 jsstr
= compiler_alloc_string(ctx
, member_expr
->identifier
);
561 return E_OUTOFMEMORY
;
563 hres
= push_instr_str(ctx
, OP_str
, jsstr
);
571 static void push_compiler_statement_ctx(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
)
575 stat_ctx
->next
= ctx
->stat_ctx
;
576 ctx
->stat_ctx
= stat_ctx
;
580 static void pop_compiler_statement_ctx(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
)
584 assert(ctx
->stat_ctx
== stat_ctx
);
585 ctx
->stat_ctx
= stat_ctx
->next
;
589 static HRESULT
compile_memberid_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, unsigned flags
)
593 if(expr
->type
== EXPR_IDENT
) {
594 identifier_expression_t
*ident_expr
= (identifier_expression_t
*)expr
;
595 return emit_identifier_ref(ctx
, ident_expr
->identifier
, flags
);
598 hres
= emit_member_expression(ctx
, expr
);
602 return push_instr_uint(ctx
, OP_memberid
, flags
);
605 static HRESULT
compile_increment_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
, jsop_t op
, int n
)
609 if(!is_memberid_expr(expr
->expression
->type
)) {
610 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
614 return push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
617 hres
= compile_memberid_expression(ctx
, expr
->expression
, fdexNameEnsure
);
621 return push_instr_int(ctx
, op
, n
);
624 /* ECMA-262 3rd Edition 11.14 */
625 static HRESULT
compile_comma_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, BOOL emit_ret
)
629 hres
= compile_expression(ctx
, expr
->expression1
, FALSE
);
633 return compile_expression(ctx
, expr
->expression2
, emit_ret
);
636 /* ECMA-262 3rd Edition 11.11 */
637 static HRESULT
compile_logical_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
642 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
646 instr
= push_instr(ctx
, op
);
648 return E_OUTOFMEMORY
;
650 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
654 set_arg_uint(ctx
, instr
, ctx
->code_off
);
658 /* ECMA-262 3rd Edition 11.12 */
659 static HRESULT
compile_conditional_expression(compiler_ctx_t
*ctx
, conditional_expression_t
*expr
)
661 unsigned jmp_false
, jmp_end
;
664 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
668 jmp_false
= push_instr(ctx
, OP_cnd_z
);
670 return E_OUTOFMEMORY
;
672 hres
= compile_expression(ctx
, expr
->true_expression
, TRUE
);
676 jmp_end
= push_instr(ctx
, OP_jmp
);
678 return E_OUTOFMEMORY
;
680 set_arg_uint(ctx
, jmp_false
, ctx
->code_off
);
681 hres
= push_instr_uint(ctx
, OP_pop
, 1);
685 hres
= compile_expression(ctx
, expr
->false_expression
, TRUE
);
689 set_arg_uint(ctx
, jmp_end
, ctx
->code_off
);
693 static HRESULT
compile_new_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
)
695 unsigned arg_cnt
= 0;
699 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
703 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
704 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
710 hres
= push_instr_uint(ctx
, OP_new
, arg_cnt
);
714 hres
= push_instr_uint(ctx
, OP_pop
, arg_cnt
+1);
718 return push_instr(ctx
, OP_push_acc
) ? S_OK
: E_OUTOFMEMORY
;
721 static HRESULT
compile_call_expression(compiler_ctx_t
*ctx
, call_expression_t
*expr
, BOOL emit_ret
)
723 unsigned arg_cnt
= 0, extra_args
;
729 if(is_memberid_expr(expr
->expression
->type
)) {
732 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
736 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
742 for(arg
= expr
->argument_list
; arg
; arg
= arg
->next
) {
743 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
749 instr
= push_instr(ctx
, op
);
751 return E_OUTOFMEMORY
;
753 instr_ptr(ctx
, instr
)->u
.arg
[0].uint
= arg_cnt
;
754 instr_ptr(ctx
, instr
)->u
.arg
[1].lng
= emit_ret
;
756 hres
= push_instr_uint(ctx
, OP_pop
, arg_cnt
+ extra_args
);
760 return !emit_ret
|| push_instr(ctx
, OP_push_acc
) ? S_OK
: E_OUTOFMEMORY
;
763 static HRESULT
compile_delete_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
767 switch(expr
->expression
->type
) {
769 binary_expression_t
*array_expr
= (binary_expression_t
*)expr
->expression
;
771 hres
= compile_expression(ctx
, array_expr
->expression1
, TRUE
);
775 hres
= compile_expression(ctx
, array_expr
->expression2
, TRUE
);
779 if(!push_instr(ctx
, OP_delete
))
780 return E_OUTOFMEMORY
;
784 member_expression_t
*member_expr
= (member_expression_t
*)expr
->expression
;
787 hres
= compile_expression(ctx
, member_expr
->expression
, TRUE
);
791 /* FIXME: Potential optimization */
792 jsstr
= compiler_alloc_string(ctx
, member_expr
->identifier
);
794 return E_OUTOFMEMORY
;
796 hres
= push_instr_str(ctx
, OP_str
, jsstr
);
800 if(!push_instr(ctx
, OP_delete
))
801 return E_OUTOFMEMORY
;
805 return push_instr_bstr(ctx
, OP_delete_ident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
807 WARN("invalid delete, unimplemented exception message\n");
809 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
813 return push_instr_uint_str(ctx
, OP_throw_type
, JS_E_INVALID_DELETE
, L
"FIXME");
820 static HRESULT
compile_assign_expression(compiler_ctx_t
*ctx
, binary_expression_t
*expr
, jsop_t op
)
822 jsop_t assign_op
= OP_throw_ref
;
823 unsigned arg_cnt
= 0;
826 if(expr
->expression1
->type
== EXPR_CALL
) {
827 call_expression_t
*call_expr
= (call_expression_t
*)expr
->expression1
;
830 if(is_memberid_expr(call_expr
->expression
->type
) && call_expr
->argument_list
) {
831 hres
= compile_memberid_expression(ctx
, call_expr
->expression
, fdexNameEnsure
);
835 for(arg
= call_expr
->argument_list
; arg
; arg
= arg
->next
) {
836 hres
= compile_expression(ctx
, arg
->expr
, TRUE
);
845 /* We need to call the functions twice: to get the value and to set it.
846 * JavaScript interpreted functions may to modify value on the stack,
847 * but assignment calls are allowed only on external functions, so we
848 * may reuse the stack here. */
849 instr
= push_instr(ctx
, OP_call_member
);
851 return E_OUTOFMEMORY
;
852 instr_ptr(ctx
, instr
)->u
.arg
[0].uint
= arg_cnt
;
853 instr_ptr(ctx
, instr
)->u
.arg
[1].lng
= 1;
855 if(!push_instr(ctx
, OP_push_acc
))
856 return E_OUTOFMEMORY
;
858 assign_op
= OP_assign_call
;
860 }else if(is_memberid_expr(expr
->expression1
->type
)) {
861 if(op
!= OP_LAST
|| expr
->expression1
->type
== EXPR_IDENT
) {
862 hres
= compile_memberid_expression(ctx
, expr
->expression1
, fdexNameEnsure
);
865 if(op
!= OP_LAST
&& !push_instr(ctx
, OP_refval
))
866 return E_OUTOFMEMORY
;
867 assign_op
= OP_assign
;
869 hres
= emit_member_expression(ctx
, expr
->expression1
);
872 assign_op
= OP_set_member
;
876 if(assign_op
== OP_throw_ref
) {
877 /* Illegal assignment: evaluate and throw */
878 hres
= compile_expression(ctx
, expr
->expression1
, TRUE
);
881 arg_cnt
= JS_E_ILLEGAL_ASSIGN
;
884 hres
= compile_expression(ctx
, expr
->expression2
, TRUE
);
888 if(op
!= OP_LAST
&& !push_instr(ctx
, op
))
889 return E_OUTOFMEMORY
;
891 return push_instr_uint(ctx
, assign_op
, arg_cnt
);
894 static HRESULT
compile_typeof_expression(compiler_ctx_t
*ctx
, unary_expression_t
*expr
)
899 if(is_memberid_expr(expr
->expression
->type
)) {
900 if(expr
->expression
->type
== EXPR_IDENT
)
901 return push_instr_bstr(ctx
, OP_typeofident
, ((identifier_expression_t
*)expr
->expression
)->identifier
);
904 hres
= compile_memberid_expression(ctx
, expr
->expression
, 0);
907 hres
= compile_expression(ctx
, expr
->expression
, TRUE
);
912 return push_instr(ctx
, op
) ? S_OK
: E_OUTOFMEMORY
;
915 static HRESULT
compile_literal(compiler_ctx_t
*ctx
, literal_t
*literal
)
917 switch(literal
->type
) {
919 return push_instr_int(ctx
, OP_bool
, literal
->u
.bval
);
921 return push_instr_double(ctx
, OP_double
, literal
->u
.dval
);
923 return push_instr(ctx
, OP_null
) ? S_OK
: E_OUTOFMEMORY
;
925 return push_instr_str(ctx
, OP_str
, literal
->u
.str
);
927 return push_instr_str_uint(ctx
, OP_regexp
, literal
->u
.regexp
.str
, literal
->u
.regexp
.flags
);
933 static HRESULT
literal_as_string(compiler_ctx_t
*ctx
, literal_t
*literal
, jsstr_t
**str
)
935 switch(literal
->type
) {
937 *str
= literal
->u
.str
;
940 return double_to_string(literal
->u
.dval
, str
);
944 return *str
? S_OK
: E_OUTOFMEMORY
;
947 static HRESULT
compile_array_literal(compiler_ctx_t
*ctx
, array_literal_expression_t
*expr
)
950 array_element_t
*iter
;
951 unsigned array_instr
;
954 array_instr
= push_instr(ctx
, OP_carray
);
956 for(iter
= expr
->element_list
; iter
; iter
= iter
->next
) {
957 length
+= iter
->elision
;
959 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
963 hres
= push_instr_uint(ctx
, OP_carray_set
, length
);
970 instr_ptr(ctx
, array_instr
)->u
.arg
[0].uint
= length
+ expr
->length
;
974 static HRESULT
compile_object_literal(compiler_ctx_t
*ctx
, property_value_expression_t
*expr
)
976 property_definition_t
*iter
;
980 if(!push_instr(ctx
, OP_new_obj
))
981 return E_OUTOFMEMORY
;
983 for(iter
= expr
->property_list
; iter
; iter
= iter
->next
) {
984 hres
= literal_as_string(ctx
, iter
->name
, &name
);
988 hres
= compile_expression(ctx
, iter
->value
, TRUE
);
992 hres
= push_instr_str_uint(ctx
, OP_obj_prop
, name
, iter
->type
);
1000 static HRESULT
compile_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
, BOOL emit_ret
)
1002 statement_ctx_t
*stat_ctx
;
1004 assert(ctx
->current_function_expr
);
1006 for(stat_ctx
= ctx
->stat_ctx
; stat_ctx
; stat_ctx
= stat_ctx
->next
)
1008 if(stat_ctx
->block_scope
)
1011 ctx
->current_function_expr
->scope_index
= stat_ctx
? stat_ctx
->scope_index
: 0;
1012 ctx
->current_function_expr
= ctx
->current_function_expr
->next
;
1014 return emit_ret
? push_instr_uint(ctx
, OP_func
, expr
->func_id
) : S_OK
;
1017 static HRESULT
compile_expression(compiler_ctx_t
*ctx
, expression_t
*expr
, BOOL emit_ret
)
1021 switch(expr
->type
) {
1023 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
1026 hres
= compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_z
);
1029 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_array
);
1032 hres
= compile_array_literal(ctx
, (array_literal_expression_t
*)expr
);
1035 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_LAST
);
1037 case EXPR_ASSIGNADD
:
1038 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_add
);
1040 case EXPR_ASSIGNAND
:
1041 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
1043 case EXPR_ASSIGNSUB
:
1044 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
1046 case EXPR_ASSIGNMUL
:
1047 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
1049 case EXPR_ASSIGNDIV
:
1050 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
1052 case EXPR_ASSIGNMOD
:
1053 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
1056 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
1058 case EXPR_ASSIGNLSHIFT
:
1059 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
1061 case EXPR_ASSIGNRSHIFT
:
1062 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
1064 case EXPR_ASSIGNRRSHIFT
:
1065 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
1067 case EXPR_ASSIGNXOR
:
1068 hres
= compile_assign_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
1071 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_and
);
1074 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_bneg
);
1077 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_or
);
1080 return compile_call_expression(ctx
, (call_expression_t
*)expr
, emit_ret
);
1082 return compile_comma_expression(ctx
, (binary_expression_t
*)expr
, emit_ret
);
1084 hres
= compile_conditional_expression(ctx
, (conditional_expression_t
*)expr
);
1087 hres
= compile_delete_expression(ctx
, (unary_expression_t
*)expr
);
1090 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_div
);
1093 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq
);
1096 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_eq2
);
1099 return compile_function_expression(ctx
, (function_expression_t
*)expr
, emit_ret
);
1101 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gt
);
1103 case EXPR_GREATEREQ
:
1104 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_gteq
);
1107 hres
= emit_identifier(ctx
, ((identifier_expression_t
*)expr
)->identifier
);
1110 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_in
);
1112 case EXPR_INSTANCEOF
:
1113 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_instanceof
);
1116 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lt
);
1119 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lteq
);
1122 hres
= compile_literal(ctx
, ((literal_expression_t
*)expr
)->literal
);
1125 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_neg
);
1128 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_lshift
);
1131 hres
= compile_member_expression(ctx
, (member_expression_t
*)expr
);
1134 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_minus
);
1137 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mod
);
1140 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_mul
);
1143 hres
= compile_new_expression(ctx
, (call_expression_t
*)expr
);
1146 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq
);
1149 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_neq2
);
1152 hres
= compile_logical_expression(ctx
, (binary_expression_t
*)expr
, OP_cnd_nz
);
1155 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_tonum
);
1158 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, -1);
1161 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_postinc
, 1);
1164 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, -1);
1167 hres
= compile_increment_expression(ctx
, (unary_expression_t
*)expr
, OP_preinc
, 1);
1170 hres
= compile_object_literal(ctx
, (property_value_expression_t
*)expr
);
1173 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift
);
1176 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_rshift2
);
1179 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_sub
);
1182 return !emit_ret
|| push_instr(ctx
, OP_this
) ? S_OK
: E_OUTOFMEMORY
;
1184 hres
= compile_typeof_expression(ctx
, (unary_expression_t
*)expr
);
1187 hres
= compile_unary_expression(ctx
, (unary_expression_t
*)expr
, OP_void
);
1190 hres
= compile_binary_expression(ctx
, (binary_expression_t
*)expr
, OP_xor
);
1192 DEFAULT_UNREACHABLE
;
1198 return emit_ret
? S_OK
: push_instr_uint(ctx
, OP_pop
, 1);
1201 static inline BOOL
is_loop_statement(statement_type_t type
)
1203 return type
== STAT_FOR
|| type
== STAT_FORIN
|| type
== STAT_WHILE
;
1206 /* ECMA-262 3rd Edition 12.1 */
1207 static HRESULT
compile_block_statement(compiler_ctx_t
*ctx
, block_statement_t
*block
, statement_t
*iter
)
1209 statement_ctx_t stat_ctx
= {0, TRUE
};
1213 needs_scope
= block
&& block
->scope_index
;
1216 if(FAILED(hres
= push_instr_uint(ctx
, OP_push_block_scope
, block
->scope_index
)))
1219 stat_ctx
.scope_index
= block
->scope_index
;
1220 stat_ctx
.block_scope
= TRUE
;
1224 hres
= compile_statement(ctx
, needs_scope
? &stat_ctx
: NULL
, iter
);
1231 if(needs_scope
&& !push_instr(ctx
, OP_pop_scope
))
1232 return E_OUTOFMEMORY
;
1237 /* ECMA-262 3rd Edition 12.2 */
1238 static HRESULT
compile_variable_list(compiler_ctx_t
*ctx
, variable_declaration_t
*list
)
1240 variable_declaration_t
*iter
;
1243 assert(list
!= NULL
);
1245 for(iter
= list
; iter
; iter
= iter
->next
) {
1250 FIXME("Constant variables are not supported.\n");
1252 hres
= emit_identifier_ref(ctx
, iter
->identifier
, 0);
1256 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
1260 if(!push_instr(ctx
, OP_assign
))
1261 return E_OUTOFMEMORY
;
1263 hres
= push_instr_uint(ctx
, OP_pop
, 1);
1271 /* ECMA-262 3rd Edition 12.2 */
1272 static HRESULT
compile_var_statement(compiler_ctx_t
*ctx
, var_statement_t
*stat
)
1274 return compile_variable_list(ctx
, stat
->variable_list
);
1277 /* ECMA-262 3rd Edition 12.4 */
1278 static HRESULT
compile_expression_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1282 hres
= compile_expression(ctx
, stat
->expr
, ctx
->from_eval
);
1286 return !ctx
->from_eval
|| push_instr(ctx
, OP_setret
) ? S_OK
: E_OUTOFMEMORY
;
1289 /* ECMA-262 3rd Edition 12.5 */
1290 static HRESULT
compile_if_statement(compiler_ctx_t
*ctx
, if_statement_t
*stat
)
1295 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1299 jmp_else
= push_instr(ctx
, OP_jmp_z
);
1301 return E_OUTOFMEMORY
;
1303 hres
= compile_statement(ctx
, NULL
, stat
->if_stat
);
1307 if(stat
->else_stat
) {
1310 jmp_end
= push_instr(ctx
, OP_jmp
);
1312 return E_OUTOFMEMORY
;
1314 set_arg_uint(ctx
, jmp_else
, ctx
->code_off
);
1316 hres
= compile_statement(ctx
, NULL
, stat
->else_stat
);
1320 set_arg_uint(ctx
, jmp_end
, ctx
->code_off
);
1322 set_arg_uint(ctx
, jmp_else
, ctx
->code_off
);
1328 /* ECMA-262 3rd Edition 12.6.2 */
1329 static HRESULT
compile_while_statement(compiler_ctx_t
*ctx
, while_statement_t
*stat
)
1331 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1335 stat_ctx
.break_label
= alloc_label(ctx
);
1336 if(!stat_ctx
.break_label
)
1337 return E_OUTOFMEMORY
;
1339 stat_ctx
.continue_label
= alloc_label(ctx
);
1340 if(!stat_ctx
.continue_label
)
1341 return E_OUTOFMEMORY
;
1343 jmp_off
= ctx
->code_off
;
1345 if(!stat
->do_while
) {
1346 label_set_addr(ctx
, stat_ctx
.continue_label
);
1347 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1351 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1356 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1360 set_compiler_loc(ctx
, stat
->stat
.loc
);
1361 if(stat
->do_while
) {
1362 label_set_addr(ctx
, stat_ctx
.continue_label
);
1363 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1367 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1372 hres
= push_instr_uint(ctx
, OP_jmp
, jmp_off
);
1376 label_set_addr(ctx
, stat_ctx
.break_label
);
1380 /* ECMA-262 10th Edition 13.7.4 */
1381 static HRESULT
compile_for_statement(compiler_ctx_t
*ctx
, for_statement_t
*stat
)
1383 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1384 statement_ctx_t scope_stat_ctx
= {0, TRUE
};
1388 if (stat
->scope_index
)
1390 if(FAILED(hres
= push_instr_uint(ctx
, OP_push_block_scope
, stat
->scope_index
)))
1393 scope_stat_ctx
.scope_index
= stat
->scope_index
;
1394 scope_stat_ctx
.block_scope
= TRUE
;
1395 push_compiler_statement_ctx(ctx
, &scope_stat_ctx
);
1398 if(stat
->variable_list
) {
1399 hres
= compile_variable_list(ctx
, stat
->variable_list
);
1402 }else if(stat
->begin_expr
) {
1403 hres
= compile_expression(ctx
, stat
->begin_expr
, FALSE
);
1408 stat_ctx
.break_label
= alloc_label(ctx
);
1409 if(!stat_ctx
.break_label
)
1411 hres
= E_OUTOFMEMORY
;
1415 stat_ctx
.continue_label
= alloc_label(ctx
);
1416 if(!stat_ctx
.continue_label
)
1418 hres
= E_OUTOFMEMORY
;
1421 expr_off
= ctx
->code_off
;
1424 set_compiler_loc(ctx
, stat
->expr_loc
);
1425 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1429 hres
= push_instr_uint(ctx
, OP_jmp_z
, stat_ctx
.break_label
);
1434 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1438 label_set_addr(ctx
, stat_ctx
.continue_label
);
1440 if(stat
->end_expr
) {
1441 set_compiler_loc(ctx
, stat
->end_loc
);
1442 hres
= compile_expression(ctx
, stat
->end_expr
, FALSE
);
1447 hres
= push_instr_uint(ctx
, OP_jmp
, expr_off
);
1451 label_set_addr(ctx
, stat_ctx
.break_label
);
1454 if (stat
->scope_index
)
1456 pop_compiler_statement_ctx(ctx
, &scope_stat_ctx
);
1457 if(SUCCEEDED(hres
) && !push_instr(ctx
, OP_pop_scope
))
1458 return E_OUTOFMEMORY
;
1463 /* ECMA-262 3rd Edition 12.6.4 */
1464 static HRESULT
compile_forin_statement(compiler_ctx_t
*ctx
, forin_statement_t
*stat
)
1466 statement_ctx_t stat_ctx
= {4, FALSE
, FALSE
};
1469 if(stat
->variable
) {
1470 hres
= compile_variable_list(ctx
, stat
->variable
);
1475 stat_ctx
.break_label
= alloc_label(ctx
);
1476 if(!stat_ctx
.break_label
)
1477 return E_OUTOFMEMORY
;
1479 stat_ctx
.continue_label
= alloc_label(ctx
);
1480 if(!stat_ctx
.continue_label
)
1481 return E_OUTOFMEMORY
;
1483 hres
= compile_expression(ctx
, stat
->in_expr
, TRUE
);
1487 if(stat
->variable
) {
1488 hres
= emit_identifier_ref(ctx
, stat
->variable
->identifier
, fdexNameEnsure
);
1491 }else if(is_memberid_expr(stat
->expr
->type
)) {
1492 hres
= compile_memberid_expression(ctx
, stat
->expr
, fdexNameEnsure
);
1496 hres
= push_instr_uint(ctx
, OP_throw_ref
, JS_E_ILLEGAL_ASSIGN
);
1500 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1504 hres
= push_instr_int(ctx
, OP_int
, DISPID_STARTENUM
);
1508 label_set_addr(ctx
, stat_ctx
.continue_label
);
1509 hres
= push_instr_uint(ctx
, OP_forin
, stat_ctx
.break_label
);
1511 return E_OUTOFMEMORY
;
1513 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1517 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.continue_label
);
1521 label_set_addr(ctx
, stat_ctx
.break_label
);
1525 static HRESULT
pop_to_stat(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
)
1527 unsigned stack_pop
= 0;
1528 statement_ctx_t
*iter
;
1531 for(iter
= ctx
->stat_ctx
; iter
!= stat_ctx
; iter
= iter
->next
) {
1532 if(iter
->using_scope
&& !push_instr(ctx
, OP_pop_scope
))
1533 return E_OUTOFMEMORY
;
1534 if(iter
->using_except
) {
1536 hres
= push_instr_uint(ctx
, OP_pop
, stack_pop
);
1541 hres
= push_instr_uint(ctx
, OP_pop_except
, ctx
->code_off
+1);
1545 stack_pop
+= iter
->stack_use
;
1549 hres
= push_instr_uint(ctx
, OP_pop
, stack_pop
);
1557 /* ECMA-262 3rd Edition 12.7 */
1558 static HRESULT
compile_continue_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1560 statement_ctx_t
*pop_ctx
;
1563 if(stat
->identifier
) {
1564 statement_t
*label_stat
;
1565 statement_ctx_t
*iter
;
1569 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1570 if(iter
->continue_label
)
1572 if(iter
->labelled_stat
&& !wcscmp(iter
->labelled_stat
->identifier
, stat
->identifier
))
1577 WARN("Label not found\n");
1578 return JS_E_LABEL_NOT_FOUND
;
1581 /* Labelled continue are allowed only on loops */
1582 for(label_stat
= iter
->labelled_stat
->statement
;
1583 label_stat
->type
== STAT_LABEL
;
1584 label_stat
= ((labelled_statement_t
*)label_stat
)->statement
);
1585 if(!is_loop_statement(label_stat
->type
)) {
1586 WARN("Label is not a loop\n");
1587 return JS_E_INVALID_CONTINUE
;
1590 assert(pop_ctx
!= NULL
);
1592 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1593 if(pop_ctx
->continue_label
)
1598 WARN("continue outside loop\n");
1599 return JS_E_INVALID_CONTINUE
;
1603 hres
= pop_to_stat(ctx
, pop_ctx
);
1607 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->continue_label
);
1610 /* ECMA-262 3rd Edition 12.8 */
1611 static HRESULT
compile_break_statement(compiler_ctx_t
*ctx
, branch_statement_t
*stat
)
1613 statement_ctx_t
*pop_ctx
;
1616 if(stat
->identifier
) {
1617 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1618 if(pop_ctx
->labelled_stat
&& !wcscmp(pop_ctx
->labelled_stat
->identifier
, stat
->identifier
)) {
1619 assert(pop_ctx
->break_label
);
1625 WARN("Label not found\n");
1626 return JS_E_LABEL_NOT_FOUND
;
1629 for(pop_ctx
= ctx
->stat_ctx
; pop_ctx
; pop_ctx
= pop_ctx
->next
) {
1630 if(pop_ctx
->break_label
&& !pop_ctx
->labelled_stat
)
1635 WARN("Break outside loop\n");
1636 return JS_E_INVALID_BREAK
;
1640 hres
= pop_to_stat(ctx
, pop_ctx
->next
);
1644 return push_instr_uint(ctx
, OP_jmp
, pop_ctx
->break_label
);
1647 /* ECMA-262 3rd Edition 12.9 */
1648 static HRESULT
compile_return_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1652 if(ctx
->from_eval
) {
1653 WARN("misplaced return statement\n");
1654 return JS_E_MISPLACED_RETURN
;
1658 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1661 if(!push_instr(ctx
, OP_setret
))
1662 return E_OUTOFMEMORY
;
1665 hres
= pop_to_stat(ctx
, NULL
);
1669 return push_instr_uint(ctx
, OP_ret
, !stat
->expr
);
1672 /* ECMA-262 3rd Edition 12.10 */
1673 static HRESULT
compile_with_statement(compiler_ctx_t
*ctx
, with_statement_t
*stat
)
1675 statement_ctx_t stat_ctx
= {0, TRUE
, FALSE
};
1678 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1682 if(!push_instr(ctx
, OP_push_with_scope
))
1683 return E_OUTOFMEMORY
;
1685 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1689 if(!push_instr(ctx
, OP_pop_scope
))
1690 return E_OUTOFMEMORY
;
1695 /* ECMA-262 3rd Edition 12.10 */
1696 static HRESULT
compile_labelled_statement(compiler_ctx_t
*ctx
, labelled_statement_t
*stat
)
1698 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
, 0, 0, stat
}, *iter
;
1701 for(iter
= ctx
->stat_ctx
; iter
; iter
= iter
->next
) {
1702 if(iter
->labelled_stat
&& !wcscmp(iter
->labelled_stat
->identifier
, stat
->identifier
)) {
1703 WARN("Label %s redefined\n", debugstr_w(stat
->identifier
));
1704 return JS_E_LABEL_REDEFINED
;
1708 /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1709 stat_ctx
.break_label
= alloc_label(ctx
);
1710 if(!stat_ctx
.break_label
)
1711 return E_OUTOFMEMORY
;
1713 hres
= compile_statement(ctx
, &stat_ctx
, stat
->statement
);
1717 label_set_addr(ctx
, stat_ctx
.break_label
);
1721 /* ECMA-262 3rd Edition 12.13 */
1722 static HRESULT
compile_switch_statement(compiler_ctx_t
*ctx
, switch_statement_t
*stat
)
1724 statement_ctx_t stat_ctx
= {0, FALSE
, FALSE
};
1725 unsigned case_cnt
= 0, *case_jmps
, i
, default_jmp
;
1726 BOOL have_default
= FALSE
;
1727 statement_t
*stat_iter
;
1728 case_clausule_t
*iter
;
1731 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1735 stat_ctx
.break_label
= alloc_label(ctx
);
1736 if(!stat_ctx
.break_label
)
1737 return E_OUTOFMEMORY
;
1739 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1744 case_jmps
= heap_alloc(case_cnt
* sizeof(*case_jmps
));
1746 return E_OUTOFMEMORY
;
1749 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1751 have_default
= TRUE
;
1755 set_compiler_loc(ctx
, iter
->loc
);
1756 hres
= compile_expression(ctx
, iter
->expr
, TRUE
);
1760 case_jmps
[i
] = push_instr(ctx
, OP_case
);
1762 hres
= E_OUTOFMEMORY
;
1768 if(SUCCEEDED(hres
)) {
1769 hres
= push_instr_uint(ctx
, OP_pop
, 1);
1770 if(SUCCEEDED(hres
)) {
1771 default_jmp
= push_instr(ctx
, OP_jmp
);
1773 hres
= E_OUTOFMEMORY
;
1778 heap_free(case_jmps
);
1783 for(iter
= stat
->case_list
; iter
; iter
= iter
->next
) {
1784 while(iter
->next
&& iter
->next
->stat
== iter
->stat
) {
1785 set_arg_uint(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
, ctx
->code_off
);
1789 set_arg_uint(ctx
, iter
->expr
? case_jmps
[i
++] : default_jmp
, ctx
->code_off
);
1791 for(stat_iter
= iter
->stat
; stat_iter
&& (!iter
->next
|| iter
->next
->stat
!= stat_iter
);
1792 stat_iter
= stat_iter
->next
) {
1793 hres
= compile_statement(ctx
, &stat_ctx
, stat_iter
);
1801 heap_free(case_jmps
);
1804 assert(i
== case_cnt
);
1807 hres
= push_instr_uint(ctx
, OP_jmp
, stat_ctx
.break_label
);
1810 set_arg_uint(ctx
, default_jmp
, ctx
->code_off
);
1813 label_set_addr(ctx
, stat_ctx
.break_label
);
1817 /* ECMA-262 3rd Edition 12.13 */
1818 static HRESULT
compile_throw_statement(compiler_ctx_t
*ctx
, expression_statement_t
*stat
)
1822 hres
= compile_expression(ctx
, stat
->expr
, TRUE
);
1826 return push_instr(ctx
, OP_throw
) ? S_OK
: E_OUTOFMEMORY
;
1829 /* ECMA-262 3rd Edition 12.14 */
1830 static HRESULT
compile_try_statement(compiler_ctx_t
*ctx
, try_statement_t
*stat
)
1832 statement_ctx_t try_ctx
= {0, FALSE
, TRUE
}, finally_ctx
= {2, FALSE
, FALSE
};
1833 unsigned push_except
, finally_off
= 0, catch_off
= 0, pop_except
, catch_pop_except
= 0;
1837 push_except
= push_instr(ctx
, OP_push_except
);
1839 return E_OUTOFMEMORY
;
1841 if(stat
->catch_block
) {
1842 ident
= compiler_alloc_bstr(ctx
, stat
->catch_block
->identifier
);
1844 return E_OUTOFMEMORY
;
1849 hres
= compile_statement(ctx
, &try_ctx
, stat
->try_statement
);
1853 pop_except
= push_instr(ctx
, OP_pop_except
);
1855 return E_OUTOFMEMORY
;
1857 if(stat
->catch_block
) {
1858 statement_ctx_t catch_ctx
= {0, TRUE
, stat
->finally_statement
!= NULL
};
1860 if(stat
->finally_statement
)
1861 catch_ctx
.using_except
= TRUE
;
1863 catch_off
= ctx
->code_off
;
1865 hres
= push_instr_bstr(ctx
, OP_enter_catch
, ident
);
1869 hres
= compile_statement(ctx
, &catch_ctx
, stat
->catch_block
->statement
);
1873 if(!push_instr(ctx
, OP_pop_scope
))
1874 return E_OUTOFMEMORY
;
1876 if(stat
->finally_statement
) {
1877 catch_pop_except
= push_instr(ctx
, OP_pop_except
);
1878 if(!catch_pop_except
)
1879 return E_OUTOFMEMORY
;
1883 if(stat
->finally_statement
) {
1885 * finally block expects two elements on the stack, which may be:
1886 * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address
1887 * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows
1889 finally_off
= ctx
->code_off
;
1890 hres
= compile_statement(ctx
, &finally_ctx
, stat
->finally_statement
);
1894 set_compiler_loc(ctx
, stat
->finally_loc
);
1895 if(!push_instr(ctx
, OP_end_finally
))
1896 return E_OUTOFMEMORY
;
1899 instr_ptr(ctx
, pop_except
)->u
.arg
[0].uint
= ctx
->code_off
;
1900 if(catch_pop_except
)
1901 instr_ptr(ctx
, catch_pop_except
)->u
.arg
[0].uint
= ctx
->code_off
;
1902 instr_ptr(ctx
, push_except
)->u
.arg
[0].uint
= catch_off
;
1903 instr_ptr(ctx
, push_except
)->u
.arg
[1].uint
= finally_off
;
1907 static HRESULT
compile_statement(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
1911 push_compiler_statement_ctx(ctx
, stat_ctx
);
1913 set_compiler_loc(ctx
, stat
->loc
);
1915 switch(stat
->type
) {
1917 hres
= compile_block_statement(ctx
, (block_statement_t
*)stat
, ((block_statement_t
*)stat
)->stat_list
);
1920 hres
= compile_break_statement(ctx
, (branch_statement_t
*)stat
);
1923 hres
= compile_continue_statement(ctx
, (branch_statement_t
*)stat
);
1930 hres
= compile_expression_statement(ctx
, (expression_statement_t
*)stat
);
1933 hres
= compile_for_statement(ctx
, (for_statement_t
*)stat
);
1936 hres
= compile_forin_statement(ctx
, (forin_statement_t
*)stat
);
1939 hres
= compile_if_statement(ctx
, (if_statement_t
*)stat
);
1942 hres
= compile_labelled_statement(ctx
, (labelled_statement_t
*)stat
);
1945 hres
= compile_return_statement(ctx
, (expression_statement_t
*)stat
);
1948 hres
= compile_switch_statement(ctx
, (switch_statement_t
*)stat
);
1951 hres
= compile_throw_statement(ctx
, (expression_statement_t
*)stat
);
1954 hres
= compile_try_statement(ctx
, (try_statement_t
*)stat
);
1957 hres
= compile_var_statement(ctx
, (var_statement_t
*)stat
);
1960 hres
= compile_while_statement(ctx
, (while_statement_t
*)stat
);
1963 hres
= compile_with_statement(ctx
, (with_statement_t
*)stat
);
1965 DEFAULT_UNREACHABLE
;
1968 pop_compiler_statement_ctx(ctx
, stat_ctx
);
1973 static inline function_local_t
*find_local(compiler_ctx_t
*ctx
, const WCHAR
*name
, unsigned int scope
)
1975 struct wine_rb_entry
*entry
= wine_rb_get(&ctx
->local_scopes
[scope
].locals
, name
);
1976 return entry
? WINE_RB_ENTRY_VALUE(entry
, function_local_t
, entry
) : NULL
;
1979 static BOOL
alloc_local(compiler_ctx_t
*ctx
, BSTR name
, int ref
, unsigned int scope
)
1981 function_local_t
*local
;
1983 local
= heap_pool_alloc(&ctx
->heap
, sizeof(*local
));
1989 wine_rb_put(&ctx
->local_scopes
[scope
].locals
, name
, &local
->entry
);
1990 ctx
->local_scopes
[scope
].locals_cnt
++;
1994 static BOOL
alloc_variable(compiler_ctx_t
*ctx
, const WCHAR
*name
, unsigned int scope
)
1998 if(find_local(ctx
, name
, scope
))
2001 ident
= compiler_alloc_bstr(ctx
, name
);
2005 return alloc_local(ctx
, ident
, ctx
->func
->var_cnt
++, scope
);
2008 static HRESULT
visit_function_expression(compiler_ctx_t
*ctx
, function_expression_t
*expr
)
2010 statement_ctx_t
*stat_ctx
;
2012 expr
->func_id
= ctx
->func
->func_cnt
++;
2013 ctx
->func_tail
= ctx
->func_tail
? (ctx
->func_tail
->next
= expr
) : (ctx
->func_head
= expr
);
2015 if(!expr
->identifier
|| expr
->event_target
)
2018 for (stat_ctx
= ctx
->stat_ctx
; stat_ctx
; stat_ctx
= stat_ctx
->next
)
2020 if (stat_ctx
->block_scope
)
2022 stat_ctx
->scope_has_functions
= TRUE
;
2027 if(!expr
->is_statement
&& ctx
->parser
->script
->version
>= SCRIPTLANGUAGEVERSION_ES5
)
2030 return alloc_variable(ctx
, expr
->identifier
, stat_ctx
? stat_ctx
->scope_index
: 0) ? S_OK
: E_OUTOFMEMORY
;
2033 static HRESULT
visit_expression(compiler_ctx_t
*ctx
, expression_t
*expr
)
2035 HRESULT hres
= S_OK
;
2037 switch(expr
->type
) {
2042 case EXPR_ASSIGNADD
:
2043 case EXPR_ASSIGNAND
:
2044 case EXPR_ASSIGNSUB
:
2045 case EXPR_ASSIGNMUL
:
2046 case EXPR_ASSIGNDIV
:
2047 case EXPR_ASSIGNMOD
:
2049 case EXPR_ASSIGNLSHIFT
:
2050 case EXPR_ASSIGNRSHIFT
:
2051 case EXPR_ASSIGNRRSHIFT
:
2052 case EXPR_ASSIGNXOR
:
2060 case EXPR_GREATEREQ
:
2062 case EXPR_INSTANCEOF
:
2075 binary_expression_t
*binary_expr
= (binary_expression_t
*)expr
;
2077 hres
= visit_expression(ctx
, binary_expr
->expression1
);
2081 hres
= visit_expression(ctx
, binary_expr
->expression2
);
2095 hres
= visit_expression(ctx
, ((unary_expression_t
*)expr
)->expression
);
2101 case EXPR_ARRAYLIT
: {
2102 array_literal_expression_t
*array_expr
= (array_literal_expression_t
*)expr
;
2103 array_element_t
*iter
;
2105 for(iter
= array_expr
->element_list
; iter
; iter
= iter
->next
) {
2106 hres
= visit_expression(ctx
, iter
->expr
);
2114 call_expression_t
*call_expr
= (call_expression_t
*)expr
;
2117 hres
= visit_expression(ctx
, call_expr
->expression
);
2121 for(arg
= call_expr
->argument_list
; arg
; arg
= arg
->next
) {
2122 hres
= visit_expression(ctx
, arg
->expr
);
2129 conditional_expression_t
*cond_expr
= (conditional_expression_t
*)expr
;
2131 hres
= visit_expression(ctx
, cond_expr
->expression
);
2135 hres
= visit_expression(ctx
, cond_expr
->true_expression
);
2139 hres
= visit_expression(ctx
, cond_expr
->false_expression
);
2143 hres
= visit_function_expression(ctx
, (function_expression_t
*)expr
);
2146 hres
= visit_expression(ctx
, ((member_expression_t
*)expr
)->expression
);
2148 case EXPR_PROPVAL
: {
2149 property_definition_t
*iter
;
2150 for(iter
= ((property_value_expression_t
*)expr
)->property_list
; iter
; iter
= iter
->next
) {
2151 hres
= visit_expression(ctx
, iter
->value
);
2157 DEFAULT_UNREACHABLE
;
2163 static HRESULT
visit_variable_list(compiler_ctx_t
*ctx
, variable_declaration_t
*list
)
2165 variable_declaration_t
*iter
;
2166 statement_ctx_t
*stat_ctx
;
2169 for(iter
= list
; iter
; iter
= iter
->next
) {
2170 for (stat_ctx
= ctx
->stat_ctx
; stat_ctx
; stat_ctx
= stat_ctx
->next
)
2172 if (stat_ctx
->block_scope
)
2176 if(!alloc_variable(ctx
, iter
->identifier
, iter
->block_scope
&& stat_ctx
? stat_ctx
->scope_index
: 0))
2177 return E_OUTOFMEMORY
;
2180 hres
= visit_expression(ctx
, iter
->expr
);
2189 static HRESULT
visit_statement(compiler_ctx_t
*,statement_ctx_t
*,statement_t
*);
2191 static HRESULT
visit_block_statement(compiler_ctx_t
*ctx
, block_statement_t
*block
, statement_t
*iter
)
2193 statement_ctx_t stat_ctx
= {0, TRUE
};
2197 needs_scope
= block
&& ctx
->parser
->script
->version
>= SCRIPTLANGUAGEVERSION_ES5
;
2200 if (!alloc_local_scope(ctx
, &block
->scope_index
))
2201 return E_OUTOFMEMORY
;
2203 stat_ctx
.scope_index
= block
->scope_index
;
2204 stat_ctx
.block_scope
= TRUE
;
2208 hres
= visit_statement(ctx
, needs_scope
? &stat_ctx
: NULL
, iter
);
2215 if (needs_scope
&& !(ctx
->local_scopes
[stat_ctx
.scope_index
].locals_cnt
|| stat_ctx
.scope_has_functions
))
2216 remove_local_scope(ctx
, block
->scope_index
);
2221 static HRESULT
visit_statement(compiler_ctx_t
*ctx
, statement_ctx_t
*stat_ctx
, statement_t
*stat
)
2223 HRESULT hres
= S_OK
;
2225 push_compiler_statement_ctx(ctx
, stat_ctx
);
2227 switch(stat
->type
) {
2229 hres
= visit_block_statement(ctx
, (block_statement_t
*)stat
, ((block_statement_t
*)stat
)->stat_list
);
2236 expression_statement_t
*expr_stat
= (expression_statement_t
*)stat
;
2237 if(expr_stat
->expr
) {
2238 if(expr_stat
->expr
->type
== EXPR_FUNC
)
2239 ((function_expression_t
*)expr_stat
->expr
)->is_statement
= TRUE
;
2240 hres
= visit_expression(ctx
, expr_stat
->expr
);
2246 expression_statement_t
*expr_stat
= (expression_statement_t
*)stat
;
2248 hres
= visit_expression(ctx
, expr_stat
->expr
);
2252 statement_ctx_t stat_ctx_data
= {0, TRUE
}, *stat_ctx
= NULL
;
2253 for_statement_t
*for_stat
= (for_statement_t
*)stat
;
2255 if(for_stat
->variable_list
)
2257 variable_declaration_t
*var
;
2259 for(var
= for_stat
->variable_list
; var
; var
= var
->next
)
2261 if (var
->block_scope
)
2263 stat_ctx
= &stat_ctx_data
;
2270 if (!alloc_local_scope(ctx
, &for_stat
->scope_index
))
2272 hres
= E_OUTOFMEMORY
;
2275 stat_ctx
->scope_index
= for_stat
->scope_index
;
2276 stat_ctx
->block_scope
= TRUE
;
2277 push_compiler_statement_ctx(ctx
, stat_ctx
);
2279 hres
= visit_variable_list(ctx
, for_stat
->variable_list
);
2281 else if(for_stat
->begin_expr
)
2282 hres
= visit_expression(ctx
, for_stat
->begin_expr
);
2285 pop_compiler_statement_ctx(ctx
, stat_ctx
);
2289 if(for_stat
->expr
) {
2290 hres
= visit_expression(ctx
, for_stat
->expr
);
2293 pop_compiler_statement_ctx(ctx
, stat_ctx
);
2298 hres
= visit_statement(ctx
, NULL
, for_stat
->statement
);
2301 pop_compiler_statement_ctx(ctx
, stat_ctx
);
2304 if(for_stat
->end_expr
)
2305 hres
= visit_expression(ctx
, for_stat
->end_expr
);
2306 pop_compiler_statement_ctx(ctx
, stat_ctx
);
2310 forin_statement_t
*forin_stat
= (forin_statement_t
*)stat
;
2312 if(forin_stat
->variable
) {
2313 hres
= visit_variable_list(ctx
, forin_stat
->variable
);
2318 hres
= visit_expression(ctx
, forin_stat
->in_expr
);
2322 if(forin_stat
->expr
) {
2323 hres
= visit_expression(ctx
, forin_stat
->expr
);
2328 hres
= visit_statement(ctx
, NULL
, forin_stat
->statement
);
2332 if_statement_t
*if_stat
= (if_statement_t
*)stat
;
2334 hres
= visit_expression(ctx
, if_stat
->expr
);
2338 hres
= visit_statement(ctx
, NULL
, if_stat
->if_stat
);
2342 if(if_stat
->else_stat
)
2343 hres
= visit_statement(ctx
, NULL
, if_stat
->else_stat
);
2347 hres
= visit_statement(ctx
, NULL
, ((labelled_statement_t
*)stat
)->statement
);
2350 switch_statement_t
*switch_stat
= (switch_statement_t
*)stat
;
2351 statement_t
*stat_iter
;
2352 case_clausule_t
*iter
;
2354 hres
= visit_expression(ctx
, switch_stat
->expr
);
2358 for(iter
= switch_stat
->case_list
; iter
; iter
= iter
->next
) {
2361 hres
= visit_expression(ctx
, iter
->expr
);
2366 for(iter
= switch_stat
->case_list
; iter
; iter
= iter
->next
) {
2367 while(iter
->next
&& iter
->next
->stat
== iter
->stat
)
2369 for(stat_iter
= iter
->stat
; stat_iter
&& (!iter
->next
|| iter
->next
->stat
!= stat_iter
);
2370 stat_iter
= stat_iter
->next
) {
2371 hres
= visit_statement(ctx
, NULL
, stat_iter
);
2379 try_statement_t
*try_stat
= (try_statement_t
*)stat
;
2381 hres
= visit_statement(ctx
, NULL
, try_stat
->try_statement
);
2385 if(try_stat
->catch_block
) {
2386 hres
= visit_statement(ctx
, NULL
, try_stat
->catch_block
->statement
);
2391 if(try_stat
->finally_statement
)
2392 hres
= visit_statement(ctx
, NULL
, try_stat
->finally_statement
);
2396 hres
= visit_variable_list(ctx
, ((var_statement_t
*)stat
)->variable_list
);
2399 while_statement_t
*while_stat
= (while_statement_t
*)stat
;
2401 hres
= visit_expression(ctx
, while_stat
->expr
);
2405 hres
= visit_statement(ctx
, NULL
, while_stat
->statement
);
2409 with_statement_t
*with_stat
= (with_statement_t
*)stat
;
2411 hres
= visit_expression(ctx
, with_stat
->expr
);
2415 hres
= visit_statement(ctx
, NULL
, with_stat
->statement
);
2418 DEFAULT_UNREACHABLE
;
2421 pop_compiler_statement_ctx(ctx
, stat_ctx
);
2426 static void resolve_labels(compiler_ctx_t
*ctx
, unsigned off
)
2430 for(instr
= ctx
->code
->instrs
+off
; instr
< ctx
->code
->instrs
+ctx
->code_off
; instr
++) {
2431 if(instr_info
[instr
->op
].arg1_type
== ARG_ADDR
&& (instr
->u
.arg
->uint
& LABEL_FLAG
)) {
2432 assert((instr
->u
.arg
->uint
& ~LABEL_FLAG
) < ctx
->labels_cnt
);
2433 instr
->u
.arg
->uint
= ctx
->labels
[instr
->u
.arg
->uint
& ~LABEL_FLAG
];
2435 assert(instr_info
[instr
->op
].arg2_type
!= ARG_ADDR
);
2438 ctx
->labels_cnt
= 0;
2441 unsigned get_location_line(bytecode_t
*code
, unsigned loc
, unsigned *char_pos
)
2443 unsigned line
= code
->start_line
;
2444 const WCHAR
*nl
, *p
;
2446 for(nl
= p
= code
->source
; p
< code
->source
+ loc
; p
++) {
2447 if(*p
!= '\n') continue;
2451 *char_pos
= loc
- (nl
- code
->source
);
2455 void release_bytecode(bytecode_t
*code
)
2462 for(i
=0; i
< code
->bstr_cnt
; i
++)
2463 SysFreeString(code
->bstr_pool
[i
]);
2464 for(i
=0; i
< code
->str_cnt
; i
++)
2465 jsstr_release(code
->str_pool
[i
]);
2467 if(code
->named_item
)
2468 release_named_item(code
->named_item
);
2469 heap_free(code
->source
);
2470 heap_pool_free(&code
->heap
);
2471 heap_free(code
->bstr_pool
);
2472 heap_free(code
->str_pool
);
2473 heap_free(code
->instrs
);
2477 static HRESULT
init_code(compiler_ctx_t
*compiler
, const WCHAR
*source
, UINT64 source_context
, unsigned start_line
)
2479 size_t len
= source
? lstrlenW(source
) : 0;
2482 return E_OUTOFMEMORY
;
2484 compiler
->code
= heap_alloc_zero(sizeof(bytecode_t
));
2486 return E_OUTOFMEMORY
;
2488 compiler
->code
->ref
= 1;
2489 compiler
->code
->source_context
= source_context
;
2490 compiler
->code
->start_line
= start_line
;
2491 heap_pool_init(&compiler
->code
->heap
);
2493 compiler
->code
->source
= heap_alloc((len
+ 1) * sizeof(WCHAR
));
2494 if(!compiler
->code
->source
) {
2495 release_bytecode(compiler
->code
);
2496 return E_OUTOFMEMORY
;
2499 memcpy(compiler
->code
->source
, source
, len
* sizeof(WCHAR
));
2500 compiler
->code
->source
[len
] = 0;
2502 compiler
->code
->instrs
= heap_alloc(64 * sizeof(instr_t
));
2503 if(!compiler
->code
->instrs
) {
2504 release_bytecode(compiler
->code
);
2505 return E_OUTOFMEMORY
;
2508 compiler
->code_size
= 64;
2509 compiler
->code_off
= 1;
2513 static HRESULT
compile_function(compiler_ctx_t
*ctx
, statement_t
*source
, function_expression_t
*func_expr
,
2514 BOOL from_eval
, function_code_t
*func
)
2516 function_expression_t
*iter
;
2517 function_local_t
*local
;
2518 unsigned off
, i
, scope
;
2523 func
->bytecode
= ctx
->code
;
2524 func
->local_ref
= INVALID_LOCAL_REF
;
2525 func
->scope_index
= 0;
2526 ctx
->func_head
= ctx
->func_tail
= NULL
;
2527 ctx
->from_eval
= from_eval
;
2529 ctx
->local_scope_count
= 0;
2530 if (!alloc_local_scope(ctx
, &scope
))
2531 return E_OUTOFMEMORY
;
2535 parameter_t
*param_iter
;
2537 if(func_expr
->identifier
) {
2538 func
->name
= compiler_alloc_bstr(ctx
, func_expr
->identifier
);
2540 return E_OUTOFMEMORY
;
2543 if(func_expr
->event_target
) {
2544 func
->event_target
= compiler_alloc_bstr(ctx
, func_expr
->event_target
);
2545 if(!func
->event_target
)
2546 return E_OUTOFMEMORY
;
2549 func
->source
= func_expr
->src_str
;
2550 func
->source_len
= func_expr
->src_len
;
2552 for(param_iter
= func_expr
->parameter_list
; param_iter
; param_iter
= param_iter
->next
)
2555 func
->params
= compiler_alloc(ctx
->code
, func
->param_cnt
* sizeof(*func
->params
));
2557 return E_OUTOFMEMORY
;
2559 for(param_iter
= func_expr
->parameter_list
, i
=0; param_iter
; param_iter
= param_iter
->next
, i
++) {
2560 func
->params
[i
] = compiler_alloc_bstr(ctx
, param_iter
->identifier
);
2561 if(!func
->params
[i
])
2562 return E_OUTOFMEMORY
;
2566 for(i
= 0; i
< func
->param_cnt
; i
++) {
2567 if(!find_local(ctx
, func
->params
[i
], 0) && !alloc_local(ctx
, func
->params
[i
], -i
-1, 0))
2568 return E_OUTOFMEMORY
;
2571 hres
= visit_block_statement(ctx
, NULL
, source
);
2575 func
->local_scope_count
= ctx
->local_scope_count
;
2576 func
->local_scopes
= compiler_alloc(ctx
->code
, func
->local_scope_count
* sizeof(*func
->local_scopes
));
2577 if(!func
->local_scopes
)
2578 return E_OUTOFMEMORY
;
2580 func
->variables
= compiler_alloc(ctx
->code
, func
->var_cnt
* sizeof(*func
->variables
));
2581 if(!func
->variables
)
2582 return E_OUTOFMEMORY
;
2584 for (scope
= 0; scope
< func
->local_scope_count
; ++scope
)
2586 func
->local_scopes
[scope
].locals
= compiler_alloc(ctx
->code
,
2587 ctx
->local_scopes
[scope
].locals_cnt
* sizeof(*func
->local_scopes
[scope
].locals
));
2588 if(!func
->local_scopes
[scope
].locals
)
2589 return E_OUTOFMEMORY
;
2590 func
->local_scopes
[scope
].locals_cnt
= ctx
->local_scopes
[scope
].locals_cnt
;
2593 WINE_RB_FOR_EACH_ENTRY(local
, &ctx
->local_scopes
[scope
].locals
, function_local_t
, entry
) {
2594 func
->local_scopes
[scope
].locals
[i
].name
= local
->name
;
2595 func
->local_scopes
[scope
].locals
[i
].ref
= local
->ref
;
2596 if(local
->ref
>= 0) {
2597 func
->variables
[local
->ref
].name
= local
->name
;
2598 func
->variables
[local
->ref
].func_id
= -1;
2602 assert(i
== ctx
->local_scopes
[scope
].locals_cnt
);
2605 func
->funcs
= compiler_alloc(ctx
->code
, func
->func_cnt
* sizeof(*func
->funcs
));
2607 return E_OUTOFMEMORY
;
2608 memset(func
->funcs
, 0, func
->func_cnt
* sizeof(*func
->funcs
));
2610 ctx
->current_function_expr
= ctx
->func_head
;
2611 off
= ctx
->code_off
;
2612 hres
= compile_block_statement(ctx
, NULL
, source
);
2616 resolve_labels(ctx
, off
);
2618 hres
= push_instr_uint(ctx
, OP_ret
, !from_eval
);
2622 if(TRACE_ON(jscript_disas
))
2623 dump_code(ctx
, off
);
2625 func
->instr_off
= off
;
2627 for(iter
= ctx
->func_head
, i
=0; iter
; iter
= iter
->next
, i
++) {
2628 hres
= compile_function(ctx
, iter
->statement_list
, iter
, FALSE
, func
->funcs
+i
);
2632 func
->funcs
[i
].scope_index
= iter
->scope_index
;
2634 TRACE("[%d] func %s, scope_index %u\n", i
, debugstr_w(func
->funcs
[i
].name
), iter
->scope_index
);
2635 if((ctx
->parser
->script
->version
< SCRIPTLANGUAGEVERSION_ES5
|| iter
->is_statement
) &&
2636 func
->funcs
[i
].name
&& !func
->funcs
[i
].event_target
) {
2637 local_ref_t
*local_ref
= lookup_local(func
, func
->funcs
[i
].name
, func
->funcs
[i
].scope_index
);
2639 func
->funcs
[i
].local_ref
= local_ref
->ref
;
2640 TRACE("found ref %s %d for %s\n", debugstr_w(local_ref
->name
), local_ref
->ref
, debugstr_w(func
->funcs
[i
].name
));
2641 if(local_ref
->ref
>= 0)
2642 func
->variables
[local_ref
->ref
].func_id
= i
;
2646 assert(i
== func
->func_cnt
);
2651 static HRESULT
parse_arguments(compiler_ctx_t
*ctx
, const WCHAR
*args
, BSTR
*arg_array
, unsigned *args_size
)
2653 const WCHAR
*ptr
= args
, *ptr2
;
2654 unsigned arg_cnt
= 0;
2656 while(iswspace(*ptr
))
2665 if(!iswalpha(*ptr
) && *ptr
!= '_') {
2666 FIXME("expected alpha or '_': %s\n", debugstr_w(ptr
));
2671 while(iswalnum(*ptr
) || *ptr
== '_')
2674 if(*ptr
&& *ptr
!= ',' && !iswspace(*ptr
)) {
2675 FIXME("unexpected har %s\n", debugstr_w(ptr
));
2680 arg_array
[arg_cnt
] = compiler_alloc_bstr_len(ctx
, ptr2
, ptr
-ptr2
);
2681 if(!arg_array
[arg_cnt
])
2682 return E_OUTOFMEMORY
;
2686 while(iswspace(*ptr
))
2691 FIXME("expected ',': %s\n", debugstr_w(ptr
));
2696 while(iswspace(*ptr
))
2701 *args_size
= arg_cnt
;
2705 static HRESULT
compile_arguments(compiler_ctx_t
*ctx
, const WCHAR
*args
)
2709 hres
= parse_arguments(ctx
, args
, NULL
, &ctx
->code
->global_code
.param_cnt
);
2713 ctx
->code
->global_code
.params
= compiler_alloc(ctx
->code
,
2714 ctx
->code
->global_code
.param_cnt
* sizeof(*ctx
->code
->global_code
.params
));
2715 if(!ctx
->code
->global_code
.params
)
2716 return E_OUTOFMEMORY
;
2718 return parse_arguments(ctx
, args
, ctx
->code
->global_code
.params
, NULL
);
2721 HRESULT
compile_script(script_ctx_t
*ctx
, const WCHAR
*code
, UINT64 source_context
, unsigned start_line
,
2722 const WCHAR
*args
, const WCHAR
*delimiter
, BOOL from_eval
, BOOL use_decode
,
2723 named_item_t
*named_item
, bytecode_t
**ret
)
2725 compiler_ctx_t compiler
= {0};
2728 hres
= init_code(&compiler
, code
, source_context
, start_line
);
2733 hres
= compile_arguments(&compiler
, args
);
2739 hres
= decode_source(compiler
.code
->source
);
2741 WARN("Decoding failed\n");
2746 hres
= script_parse(ctx
, &compiler
, compiler
.code
, delimiter
, from_eval
, &compiler
.parser
);
2748 release_bytecode(compiler
.code
);
2752 heap_pool_init(&compiler
.heap
);
2753 hres
= compile_function(&compiler
, compiler
.parser
->source
, NULL
, from_eval
, &compiler
.code
->global_code
);
2754 heap_free(compiler
.local_scopes
);
2755 heap_pool_free(&compiler
.heap
);
2756 parser_release(compiler
.parser
);
2758 if(hres
!= DISP_E_EXCEPTION
)
2759 throw_error(ctx
, hres
, NULL
);
2760 set_error_location(ctx
->ei
, compiler
.code
, compiler
.loc
, IDS_COMPILATION_ERROR
, NULL
);
2761 release_bytecode(compiler
.code
);
2762 return DISP_E_EXCEPTION
;
2766 compiler
.code
->named_item
= named_item
;
2770 *ret
= compiler
.code
;